[英]Is there a way to find out about a png image transparency by reading the image header?
有沒有一種方法可以通過讀取圖像標題來了解png圖像的透明度?
在對每個像素的GetPixel
性能不佳發表評論之后,我嘗試編寫一個代碼段,以查找圖像(包括PNG)中是否存在透明像素。 這里是。
public static bool IsImageTransparent(string fullName)
{
using (Bitmap bitmap = Bitmap.FromFile(fullName) as Bitmap)
{
bool isTransparent;
// Not sure if the following enumeration is correct. Maybe some formats do not actually allow transparency.
PixelFormat[] formatsWithAlpha = new[] { PixelFormat.Indexed, PixelFormat.Gdi, PixelFormat.Alpha, PixelFormat.PAlpha, PixelFormat.Canonical, PixelFormat.Format1bppIndexed, PixelFormat.Format4bppIndexed, PixelFormat.Format8bppIndexed, PixelFormat.Format16bppArgb1555, PixelFormat.Format32bppArgb, PixelFormat.Format32bppPArgb, PixelFormat.Format64bppArgb, PixelFormat.Format64bppPArgb };
if (formatsWithAlpha.Contains(bitmap.PixelFormat))
{
// There might be transparency.
BitmapData binaryImage = bitmap.LockBits(new Rectangle(Point.Empty, bitmap.Size), ImageLockMode.ReadOnly, PixelFormat.Format64bppArgb);
unsafe
{
byte* pointerToImageData = (byte*)binaryImage.Scan0;
int numberOfPixels = bitmap.Width * bitmap.Height;
isTransparent = false;
// 8 bytes = 64 bits, since our image is 64bppArgb.
for (int i = 0; i < numberOfPixels * 8; i += 8)
{
// Check the last two bytes (transparency channel). First six bytes are for R, G and B channels. (0, 32) means 100% opacity.
if (pointerToImageData[i + 6] != 0 || pointerToImageData[i + 7] != 32)
{
isTransparent = true;
break;
}
}
}
bitmap.UnlockBits(binaryImage);
}
else
{
// No transparency available for this image.
isTransparent = false;
}
return isTransparent;
}
}
優點:
GetPixel
快得多, 缺點:
unsafe
, 較不手動的方法是使用調色板。 可能存在一些.NET Framework或第三方庫,您可以通過這樣做。 我嘗試了以下操作(使用WPF):
using (Stream imageStreamSource = new FileStream(fullName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
PngBitmapDecoder decoder = new PngBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource bitmapSource = decoder.Frames[0];
return bitmapSource.Palette.Colors.Any(c => c.A != 0);
}
但是我不工作 ,因為bitmapSource.Palette
是null
的。 此外,與第一個片段相比,使用調色板會嚴重降低性能,因為在繼續操作之前必須將每種顏色加載到顏色列表中。
找出什么? 圖像是否透明? 您可以檢查位深度,24位(RGB)通常表示沒有透明度,而32位(RGBA)則表示存在不透明/透明層
有時,您可以告訴您,如果位深度為24或更低,並且所有調色板成員均不包含相關的Alpha值,則絕對不具有透明度(您不必說是否要將部分透明度計為透明或不透明。不)。
但是,要確保實際上有一定的透明度,確實需要檢查整個圖像。 因此,對於流大小,它為O(n)(對於圖像大小,它大約為O(x * y)),但在某些情況下,標頭可能會出現捷徑。
如果為png編制了索引,則可以檢查TRNS塊Png塊描述 。 如果不是,則需要像在該方法中那樣逐個獲取它。
感謝大家。 通過使用ChrisF的鏈接使它正常工作感謝ChrisF, 確定圖像中是否使用了Alpha通道 。
這是我的代碼:
private bool IsImageTransparent(Bitmap image)
{
for (int i = 0; i < image.Width; i++)
for (int j = 0; j < image.Height; j++)
{
var pixel = image.GetPixel(i, j);
if (pixel.A != 255)
return true;
}
return false;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.