c# - 使用 WriteableBitmap 修改 JPG 图像的像素
问题描述
我对 C# 和 WPF 编程相当陌生。我目前正在尝试弄清楚如何使用 WriteableBitmap 修改 JPG 图像。我想我得到了正在发生的事情的一般要点,但我正在观察一种我不理解的奇怪行为。
以下是基于以下示例代码的情况: 如果我使用当前已注释掉的构造函数(在第 29 行)声明 WriteableBitmap,我可以使用所示代码修改像素并在其中绘制一个带有红色方块的黑色区域。这是我设置和写入像素的工作测试用例。
但是,如果我注释掉第 29 行并使用 JPG 图像创建一个 WriteableBitmap(因为它当前已编码——参见第 31 行),图像本身加载正常,但我尝试覆盖的红色方块和黑色方块(以及以前工作过),不再出现。
谁能解释为什么会这样?在第二种方法中,我没有声明 dPiX 和 dPiY 参数的值,也无法在任何地方指定 BGRA32 的 PixelFormat。由于这些是只读的,我无法修改它们。这是我问题的根源吗?如果是这样,有没有办法解决这个问题?
我觉得这是一个非常基本的东西,我只是忽略了。任何指导将不胜感激。在此先感谢您的时间。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Drawing;
using System.IO;
namespace AsciiArt
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
//Test code to load a JPG and then write over top of it using writeable bitmaps
private void SampleWriteableBitmap()
{
// Create a writeable bitmap (which is a valid WPF image source
//WriteableBitmap wbmap = new WriteableBitmap(100, 100, 96, 96, PixelFormats.Bgra32, null);
WriteableBitmap wbmap = ConvertToBitmap("../../photos/Image1.JPG");
// Overwriting the image by making all pixels black -- a silly test I know.
for (int x = 0; x < wbmap.PixelWidth; ++x)
{
for (int y = 0; y < wbmap.PixelHeight; ++y)
{
// apply pixels to bitmap
//Colors are A, Red, Green, Blue. A must be 255 to be opaque
// A R G B
SetPixel(wbmap, x, y, System.Drawing.Color.FromArgb(255, 0, 0, 0));
}
}
// and then creating a smaller block of a different color -- again as a test.
for (int x = 0; x < 20; ++x)
{
for (int y = 0; y < 20; ++y)
{
// apply pixels to bitmap
//Colors are A, Red, Green, Blue. A must be 255 to be opaque
// A R G B
SetPixel(wbmap, x, y, System.Drawing.Color.FromArgb(255, 255, 0, 0));
}
}
// Display some parameters for debugging...
ByteReadData.Text = "wbmap.PixelHeight: " + wbmap.PixelHeight + " wbmap.PixelWidth: " +
wbmap.PixelWidth + " wbmap.Format: " + wbmap.Format.BitsPerPixel + " ---> " +
wbmap.PixelHeight * wbmap.PixelWidth * wbmap.Format.BitsPerPixel / 8 + " wbmap.dpix: " + wbmap.DpiX + " wbmap.dpiy: " + wbmap.DpiY;
// set image source to the new bitmap
convertedPhoto.Source = wbmap;
}
// function to convert a JPG or other file type to a Bitmap
public WriteableBitmap ConvertToBitmap(string fileName)
{
BitmapImage bitmap = new BitmapImage(new Uri(fileName, UriKind.Relative));
WriteableBitmap newbitmap = new WriteableBitmap(bitmap);
return newbitmap;
}
public void SetPixel(WriteableBitmap wbm, int x, int y, System.Drawing.Color c)
{
if (y > wbm.PixelHeight - 1 || x > wbm.PixelWidth - 1) return;
if (y < 0 || x < 0) return;
if (!wbm.Format.Equals(PixelFormats.Bgra32)) return;
wbm.Lock();
IntPtr buff = wbm.BackBuffer;
int Stride = wbm.BackBufferStride;
unsafe
{
byte* pbuff = (byte*)buff.ToPointer();
int loc = y * Stride + x * 4;
pbuff[loc] = c.B;
pbuff[loc + 1] = c.G;
pbuff[loc + 2] = c.R;
pbuff[loc + 3] = c.A;
}
wbm.AddDirtyRect(new Int32Rect(x, y, 1, 1));
wbm.Unlock();
}
public MainWindow()
{
InitializeComponent();
SampleWriteableBitmap();
}
}
} }
解决方案
推荐阅读
- hyperledger-fabric - 同时使用“X509 MSP”和“idemix MSP”
- google-bigquery - BigQuery 是否有基于规则或基于成本的优化器或其他?
- python - 如何使用 OpenVINO 预训练模型?
- excel - 如何在两列中添加(总和)项目
- omnipay - 如果您不拥有服务器,是否可以使用 Omnipay?
- php - 如何从php中的关联数组创建二维数组
- r - 有没有办法使用 `sf::st_join` 来获取捕获区域的比例?
- dart - Flutter 在按下按钮时弹出一个列表,并在选择一个选项后关闭该列表
- flutter - 当我导航到其他页面并返回时,带有 http 请求的 Flutter Listview.builder 会异常刷新
- java - 我应该如何在不使用数组的情况下生成随机数列表并确定最大的?