如何使用 SkiaSharp 查找解码位图的 PixelFormat
How to find PixelFormat for decoded bitmap using SkiaSharp
在System.Drawing中我们从Image对象中获取PixelFormat,但是SkiaSharp.SkImage没有提供API来寻找解码图像的PixelFormat。它是否有任何其他解决方法来找到解码图像的 PixelFormat,以及我们如何创建 PixelFormat 值相当于 System.Drawing.Image
的图像
简答
有这个方面,但分为SKColorType
和SKAlphaType
两种。这些属性位于 SKImageInfo
类型上。
SKImage
对比 SKBitmap
在我分享真正的答案之前,先简单介绍一下这两种图像类型之间的区别。
SKBitmap
(仅限光栅)
A SKBitmap
是一个 纯光栅图形 ,这意味着颜色和 alpha 类型信息很容易获得。这是在Info
属性。
SKBitmap bitmap = ...;
SKColorType colorType = bitmap.Info.ColorType;
SKAlphaType alphaType = bitmap.Info.AlphaType;
SKImage
(光栅或纹理)
SKImage
有点不同,因为它实际上可能不是光栅位图。 SKImage
可以是 GPU 对象,例如 OpenGL 纹理。因此,这种颜色类型不适用。因此,在您使用光栅位图的情况下,请使用 SKBitmap
而不是 SKImage
.
但是,SKImage
仍有希望,因为基于光栅的 SKImage
实际上在底层使用了 SKBitmap
。如果您知道您的 SKImage
是光栅图像,那么您可以使用 PeekPixels()
方法获取一个 SKPixmap
对象,该对象也将有一个 Info
属性。 SKPixmap
是一个精简类型,包含对图像数据的引用、信息和一些其他属性。
要检查某个SKImage
是纹理图像还是光栅图像,可以使用IsTextureBacked
属性.
SKImage image = ...;
if (!image.IsTextureBacked) {
using (SKPixmap pixmap = image.PeekPixels()) {
SKColorType colorType = pixmap.ColorType;
SKAlphaType alphaType = pixmap.AlphaType;
}
} else {
// this is a texture on the GPU and can't be determined easily
}
更长的答案
所以现在更长的答案... SKColorType
和 SKAlphaType
类型一起构成了 PixelFormat
.
的等价物
例如:
PixelFormat.Format16bppRgb565
等同于:
SKColorType.Rgb565
and SKAlphaType.Opaque
PixelFormat.Format32bppArgb
等同于:
SKColorType.Rgba8888
(or SKColorType.Bgra8888
on Windows) and SKAlphaType.Unpremul
PixelFormat.Format32bppPArgb
等同于:
SKColorType.Rgba8888
(or SKColorType.Bgra8888
on Windows) and SKAlphaType.Premul
Rgba8888
和 Bgra8888
之间的主要区别是应用 运行 所在的平台。通常,您会根据 SKImageInfo.PlatformColorType
检查颜色类型,因为这将知道本机颜色类型应该是什么。
在System.Drawing中我们从Image对象中获取PixelFormat,但是SkiaSharp.SkImage没有提供API来寻找解码图像的PixelFormat。它是否有任何其他解决方法来找到解码图像的 PixelFormat,以及我们如何创建 PixelFormat 值相当于 System.Drawing.Image
的图像简答
有这个方面,但分为SKColorType
和SKAlphaType
两种。这些属性位于 SKImageInfo
类型上。
SKImage
对比 SKBitmap
在我分享真正的答案之前,先简单介绍一下这两种图像类型之间的区别。
SKBitmap
(仅限光栅)
A SKBitmap
是一个 纯光栅图形 ,这意味着颜色和 alpha 类型信息很容易获得。这是在Info
属性。
SKBitmap bitmap = ...;
SKColorType colorType = bitmap.Info.ColorType;
SKAlphaType alphaType = bitmap.Info.AlphaType;
SKImage
(光栅或纹理)
SKImage
有点不同,因为它实际上可能不是光栅位图。 SKImage
可以是 GPU 对象,例如 OpenGL 纹理。因此,这种颜色类型不适用。因此,在您使用光栅位图的情况下,请使用 SKBitmap
而不是 SKImage
.
但是,SKImage
仍有希望,因为基于光栅的 SKImage
实际上在底层使用了 SKBitmap
。如果您知道您的 SKImage
是光栅图像,那么您可以使用 PeekPixels()
方法获取一个 SKPixmap
对象,该对象也将有一个 Info
属性。 SKPixmap
是一个精简类型,包含对图像数据的引用、信息和一些其他属性。
要检查某个SKImage
是纹理图像还是光栅图像,可以使用IsTextureBacked
属性.
SKImage image = ...;
if (!image.IsTextureBacked) {
using (SKPixmap pixmap = image.PeekPixels()) {
SKColorType colorType = pixmap.ColorType;
SKAlphaType alphaType = pixmap.AlphaType;
}
} else {
// this is a texture on the GPU and can't be determined easily
}
更长的答案
所以现在更长的答案... SKColorType
和 SKAlphaType
类型一起构成了 PixelFormat
.
例如:
PixelFormat.Format16bppRgb565
等同于:
SKColorType.Rgb565
andSKAlphaType.Opaque
PixelFormat.Format32bppArgb
等同于:
SKColorType.Rgba8888
(orSKColorType.Bgra8888
on Windows) andSKAlphaType.Unpremul
PixelFormat.Format32bppPArgb
等同于:
SKColorType.Rgba8888
(orSKColorType.Bgra8888
on Windows) andSKAlphaType.Premul
Rgba8888
和 Bgra8888
之间的主要区别是应用 运行 所在的平台。通常,您会根据 SKImageInfo.PlatformColorType
检查颜色类型,因为这将知道本机颜色类型应该是什么。