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