c#_具有索引像素格式的图像不支持 SetPixel

首先呢我们要明白各种图片格式,不同的图片格式成像也是不同的,对于索引类型的图片,其文件头部有一个颜色表,这个表按照一定的规律存储了所有的可能在这张图片中出现的颜色。它的每一个点的像素值(ARGB)并不是直接存储的。在存储具体点的数据的地方之只是存储其在颜色表中的索引,在进行的解码的时候,读取索引然后在颜色表中查找,找到对应所以的颜色值之后将其显示出来作为这个点的颜色值。
System.Drawing.Image不支持通过索引的方式存储图片数据的图片实现setpixel,-_-\\心累(我觉得完全可以实现的啊)
可是这又有什么关系呢!
我们可以通过Bitmap.Clone()来将索引图片的像素数据拷贝到我们新建的图片上,并且在函数中指定我们新图片的pixelFormat (这次就不要设置成什么索引类型的啦!)接下来就是对我们新建的图片进行操作啦。。。想怎么玩就怎么玩的!

Bitmap indexImg = new Bitmap(“fileName.jpg”);
Bitmap newImg = indexImg.Clone(new Rectangle(0,0,indexImg.Width,indexImg.Height),PixelFormat.Format24bppRgb);
// do something you want
// example : setPixel() …..
// balabalabla

如果使用 `SetPixel` 方法设置每个像素的颜色,可能会导致性能问题,因为该方法需要频繁地锁定位图并访问它的像素数据。因此,建议使用 `LockBits` 方法来访问位图数据,然后使用 `Unsafe` 代码块来执行图像处理操作。 以下是一个使用 `LockBits` 和 `Unsafe` 实现的 C# 代码示例,可以将24位图像转换为8位图像: ```csharp public static Bitmap ConvertTo8bpp(Bitmap bmp) { // 创建一个新的8位位图 Bitmap newBmp = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format8bppIndexed); // 创建调色板 ColorPalette pal = newBmp.Palette; for (int i = 0; i < 256; i++) { pal.Entries[i] = Color.FromArgb(i, i, i); } newBmp.Palette = pal; // 访问位图数据 BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); BitmapData newBmpData = newBmp.LockBits(new Rectangle(0, 0, newBmp.Width, newBmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); int stride = bmpData.Stride; int newStride = newBmpData.Stride; IntPtr bmpScan0 = bmpData.Scan0; IntPtr newBmpScan0 = newBmpData.Scan0; // 将RGB值转换成索引并写入新位图数据 unsafe { byte* bmpPtr = (byte*)bmpScan0.ToPointer(); byte* newBmpPtr = (byte*)newBmpScan0.ToPointer(); for (int y = 0; y < bmp.Height; y++) { byte* bmpRow = bmpPtr + y * stride; byte* newBmpRow = newBmpPtr + y * newStride; for (int x = 0; x < bmp.Width; x++) { byte b = bmpRow[x * 3]; byte g = bmpRow[x * 3 + 1]; byte r = bmpRow[x * 3 + 2]; int index = (int)(0.299 * r + 0.587 * g + 0.114 * b); newBmpRow[x] = (byte)index; } } } // 解锁位图数据 bmp.UnlockBits(bmpData); newBmp.UnlockBits(newBmpData); return newBmp; } ``` 在这个示例中,使用了 `LockBits` 方法来访问位图数据,并使用 `Unsafe` 代码块来执行图像处理操作,从而提高了性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值