我正在处理图像软件,现在我想更改白平衡并在照片上添加一些饱和度,所以我必须处理每个像素值。 我试图将我的BitmapImage转换为WritableBitmap,然后尝试了这段代码。但是,如果我运行它,我的图像会变成绿色。 我想从该图像中获取像素,然后将其设置为新值。 我搜索了许多解决方案,但没有找到任何解决方案,因此也许有人可以帮助我编写代码。谢谢。
public static WriteableBitmap Colors(Bitmap Image)
{
int width = Image.Width;
int height = Image.Width;
byte[,,] pixels = new byte[height, width, 4];
WriteableBitmap wbitmap = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgra32, null);
var target = new Bitmap(Image.Width, Image.Height);
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
pixels[i, j, 1] -= 30;
pixels[i, j, 3] -= 30;
}
}
byte[] pixels1d = new byte[height * width * 4];
int index = 0;
for (int row = 0; row < height; row++)
{
for (int col = 0; col < width; col++)
{
for (int i = 0; i < 4; i++)
pixels1d[index++] = pixels[row, col, i];
}
}
Int32Rect rect = new Int32Rect(0, 0, width, height);
int stride = 4 * width;
wbitmap.WritePixels(rect, pixels1d, stride, 0);
return wbitmap;
}
然后我像这样运行它:
private void run_OnClick(object sender, RoutedEventArgs e)
{
// Contrastt(BitmapImage2Bitmap(bitmap), 10);
// MedianFilter(BitmapImage2Bitmap(bitmap),5);
WriteableBitmap writeableBitmap = new WriteableBitmap(imageX);
BitmapImage colored = ConvertWriteableBitmapToBitmapImage(Colors((BitmapImage2Bitmap(bitmap))));
ImageBrush brush = new ImageBrush();
brush.ImageSource = imageX ;
CanvasProcessedImage.Background = brush;
}
答案 0 :(得分:0)
假设您已经有一个source
变量的BitmapSource(或类似BitmapImage的派生类的实例),则首先要创建一个具有已知像素格式的BitmapSource,然后根据该像素创建一个WritabelBitmap:
// source is a BitmapSource with whatever PixelFormat
var format = PixelFormats.Bgra32;
var temp = new FormatConvertedBitmap(source, format, null, 0); // force BGRA
var bitmap = new WriteableBitmap(temp);
现在,您可以直接在WriteableBitmap的BackBuffer
属性中操作数据,或者首先更简单一些,然后按如下所示创建缓冲区的副本:
var width = bitmap.PixelWidth;
var height = bitmap.PixelHeight;
var stride = bitmap.BackBufferStride;
var buffer = new byte[stride * height];
bitmap.CopyPixels(buffer, stride, 0);
然后操作缓冲区并将其写回到WriteableBitmap。既然已经指定了PixelFormat,就知道每个4字节像素值中的哪个字节分别是B,G,R和A。
for (int i = 0; i < buffer.Length; i += 4)
{
// Blue
//buffer[i + 0] = ...
// Green
buffer[i + 1] = (byte)Math.Max(buffer[i + 1] - 30, 0);
// Red
buffer[i + 2] = (byte)Math.Max(buffer[i + 2] - 30, 0);
// Alpha
//buffer[i + 3] = ...
}
bitmap.WritePixels(new Int32Rect(0, 0, width, height), buffer, stride, 0);
在将WriteableBitmap分配给Image元素的Source
属性或ImageBrush的ImageSource
属性后,您可以稍后再调用WritePixels
(并根据需要多次调用)无需将其重新分配给Source
/ ImageSource
属性。更改为“就地”。