6
A
回答
6
在.NET位圖格式中,不存在8位或4位灰度圖像。支持的格式由PixelFormat enumeration列舉。但是,您可以通過創建索引圖像(8bppIndexed或4bppIndexed)來創建4或8位圖像,其中調色板中的每個條目都是灰度值。
這段代碼使用位圖,並創建一個副本,與灰度值的8bpp的索引圖像:
public static Bitmap BitmapToGrayscale(Bitmap source)
{
// Create target image.
int width = source.Width;
int height = source.Height;
Bitmap target = new Bitmap(width,height,PixelFormat.Format8bppIndexed);
// Set the palette to discrete shades of gray
ColorPalette palette = target.Palette;
for(int i = 0 ; i < palette.Entries.Length ; i++)
{
palette.Entries[i] = Color.FromArgb(0,i,i,i);
}
target.Palette = palette;
// Lock bits so we have direct access to bitmap data
BitmapData targetData = target.LockBits(new Rectangle(0, 0, width,height),
ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
BitmapData sourceData = source.LockBits(new Rectangle(0, 0, width,height),
ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
unsafe
{
for(int r = 0 ; r < height ; r++)
{
byte* pTarget = (byte*) (targetData.Scan0 + r*targetData.Stride);
byte* pSource = (byte*) (sourceData.Scan0 + r*sourceData.Stride);
for(int c = 0 ; c < width ; c++)
{
byte colorIndex = (byte) (((*pSource)*0.3 + *(pSource + 1)*0.59 + *(pSource + 2)*0.11));
*pTarget = colorIndex;
pTarget++;
pSource += 3;
}
}
}
target.UnlockBits(targetData);
source.UnlockBits(sourceData);
return target;
}
爲了使4Bpp圖像,而不是,你就需要用的PixelFormat創建目標。 Format4bppIndexed,然後將ColorPalette設置爲16個不連續的灰色陰影。最後,在循環中,您應該將值2歸一化爲0-15,並將每個2個像素值打包爲一個字節。
這是修改後的代碼,以使一個4bpp灰度圖像:
public static Bitmap BitmapToGrayscale4bpp(Bitmap source)
{
// Create target image.
int width = source.Width;
int height = source.Height;
Bitmap target = new Bitmap(width,height,PixelFormat.Format4bppIndexed);
// Set the palette to discrete shades of gray
ColorPalette palette = target.Palette;
for(int i = 0 ; i < palette.Entries.Length ; i++)
{
int cval = 17*i;
palette.Entries[i] = Color.FromArgb(0,cval,cval,cval);
}
target.Palette = palette;
// Lock bits so we have direct access to bitmap data
BitmapData targetData = target.LockBits(new Rectangle(0, 0, width,height),
ImageLockMode.ReadWrite, PixelFormat.Format4bppIndexed);
BitmapData sourceData = source.LockBits(new Rectangle(0, 0, width,height),
ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
unsafe
{
for(int r = 0 ; r < height ; r++)
{
byte* pTarget = (byte*) (targetData.Scan0 + r*targetData.Stride);
byte* pSource = (byte*) (sourceData.Scan0 + r*sourceData.Stride);
byte prevValue = 0;
for(int c = 0 ; c < width ; c++)
{
byte colorIndex = (byte) ((((*pSource)*0.3 + *(pSource + 1)*0.59 + *(pSource + 2)*0.11))/16);
if (c % 2 == 0)
prevValue = colorIndex;
else
*(pTarget++) = (byte)(prevValue | colorIndex << 4);
pSource += 3;
}
}
}
target.UnlockBits(targetData);
source.UnlockBits(sourceData);
return target;
}
相關問題
- 1. 減少位圖大小
- 2. 減少Android中位圖的總大小而不損失質量
- 3. Android JPEG到位圖=大小減小
- 4. 減少圖像大小(以KB爲單位)
- 5. 減少圖像位深度
- 6. 減少uclinux圖像大小
- 7. 減少顏色數量的位圖 - 不應該減小尺寸?
- 8. 減少內存中的圖像大小
- 9. 如何減少gridview列中的小數位數asp.net C#
- 10. 減小位圖圖像的物理大小?
- 11. 以KB爲單位減少Flash文件的大小?
- 12. 移位/減少Bision
- 13. 位圖的位圖大小(inSampleSize * inSampleSize)android
- 14. 減少TimePicker大小
- 15. 減少BitmapDrawable大小
- 16. 將圖像轉換爲位圖並減小其大小
- 17. 如何減少C#中的圖像大小?
- 18. 減少圖像的文件大小
- 19. 減少散點圖的文件大小
- 20. 如何減少圖片的大小?
- 21. 減少Matplotlib底圖的大小
- 22. Docker - 減少拉的大小
- 23. 減少dll的大小vC++
- 24. 減少紋理的大小
- 25. Solr大小的減少
- 26. 減少listitem的大小?
- 27. C++中64位計算機的指針大小是多少?
- 28. 如何使一個規模動畫減小視圖大小(位)
- 29. 野牛減少/減少,移位/減少衝突
- 30. 分析器移位/減少減少/減少衝突
BitmapToGrayscale4bpp'的'最後部分有一個小錯誤:'(字節)(prevValue | colorIndex << 4)'應該是' (字節)(prevValue << 4 | colorIndex)'。 prevValue半字節應該在輸出字節中的colorIndex半字節之前。 – lnmx 2011-11-28 16:18:02