【发布时间】:2021-01-30 15:42:39
【问题描述】:
我构建了一个小型测试示例,目标是将.png 中的所有像素更改为白色。我正在使用BitmapData,因为据我了解,性能更好。如果我能让它工作;然后我可以更改要更改的像素并添加不同的条件来更改像素颜色。但我只坚持这个简单的测试。
这是我的 C#:
public static void TestConvertAllBlackBitmapToAllWhite()
{
string allBlackPNGFullFilePath = @"C:\Users\{Username}\Desktop\50x50AllBlack.png";
Bitmap allBlackBitmap = new Bitmap(allBlackPNGFullFilePath);
Bitmap newBitmap = (Bitmap)allBlackBitmap.Clone();
Size size = newBitmap.Size;
PixelFormat pixelFormat = newBitmap.PixelFormat;
byte bitDepth = (byte)(pixelFormat == PixelFormat.Format32bppArgb ? 4 : 3);
Rectangle rectangle = new Rectangle(Point.Empty, size);
BitmapData bitmapData = newBitmap.LockBits(rectangle, ImageLockMode.ReadOnly, pixelFormat);
int dataSize = bitmapData.Stride * bitmapData.Height;
byte[] data = new byte[dataSize];
Marshal.Copy(bitmapData.Scan0, data, 0, dataSize);
Color white = Color.White;
for (int y = 0; y < size.Height; y++)
{
for (int x = 0; x < size.Width; x++)
{
// Get Index
int index = y * bitmapData.Stride + x * bitDepth;
// Set Pixel Color
data[index] = white.B;
data[index + 1] = white.G;
data[index + 2] = white.R;
}
}
Marshal.Copy(data, 0, bitmapData.Scan0, data.Length);
newBitmap.UnlockBits(bitmapData);
// Save New Converted Bitmap
string originalFileName = Path.GetFileNameWithoutExtension(allBlackPNGFullFilePath);
string directory = Path.GetDirectoryName(allBlackPNGFullFilePath);
string newBitmapFileName = originalFileName + "_Converted";
string newBitmapFullFileName = directory + Path.DirectorySeparatorChar.ToString() + newBitmapFileName + ".png";
newBitmap.Save(newBitmapFullFileName, ImageFormat.Png);
}
问题是我得到的输出是另一个全黑 .png 而不是全白。
如何修复我的简单示例代码以生成全白的.png?
任何帮助/指导将不胜感激。
【问题讨论】:
-
您正在读取 png 文件,但从未设置 alpha 通道。尝试添加
data[index + 3] = white.A;! -
不,这不可能! - Format32bppArgb' 必须是 bitDepth = 4 !!
-
真的吗?那么错误就是以只读方式打开数据。将其设为
BitmapData bitmapData = newBitmap.LockBits(rectangle, ImageLockMode.ReadWrite, pixelFormat);,它将起作用。 -
是的,我自己错过了 3 次。对于灵活的代码,我仍然会添加类似
if (bitDepth == 4 ) data[index + 3] = white.A; -
对于将位图更改为纯白色,我真的认为这不是最有效的方法;相当确定普通绘图类有一个简单的
Fill来做到这一点。此外,你应该在完成后处理你的东西。顺便说一句,使用您使用的方法,完全不需要克隆。你也可以只复制字节然后解锁并处理原始图像,然后你可以将这些字节构建成一个新图像并将其保存回相同的文件名。
标签: c# bitmap bitmapdata