【问题标题】:Change the pixel color of a bitmap in C#在 C# 中更改位图的像素颜色
【发布时间】:2021-09-12 14:36:54
【问题描述】:
  public partial class Form1 : Form
    {
        Image File;

        public Form1()
        {
            InitializeComponent();
        }

        private void Import_Click(object sender, EventArgs e)
        {
            OpenFileDialog f = new OpenFileDialog();
            f.Filter = "Image files (*.jpg, *.png) | *.jpg; *.png";
            if (f.ShowDialog() == DialogResult.OK)
            {
                File = Image.FromFile(f.FileName);
                pictureBox1.Image = File;
            }
        }

        private void Export_Click(object sender, EventArgs e)
        {
            Bitmap image = new Bitmap(File);
            image.SetPixel(50, 50, Color.Black);
            SaveFileDialog f = new SaveFileDialog();
            f.Filter = "JPG(*.JPG)|*.jpg";
            if (f.ShowDialog() == DialogResult.OK)
            {
                File.Save(f.FileName);
            }
        }
    }

我想做的是导入一张图片,改变一个像素的颜色,然后导出。

我做错了什么? 提前致谢。

【问题讨论】:

    标签: c# image winforms bitmap pixel


    【解决方案1】:

    您的代码实际上存在几个问题:

    • 您没有关闭您打开的图像的文件流,这意味着您将永远无法将修改后的图像保存为相同的文件名。事实上,在您的程序关闭之前,任何程序都无法覆盖该文件。
    • 您不检查是否可以编辑;打开任一维度小于 51 像素的图像,保存操作将崩溃。
    • 您只提供另存为 jpeg...一种格式,其中单个像素的变化将不可避免地被压缩弄脏。
    • 没有实际上保存为 jpeg。不指定类型的默认保存将使图像最终为 png 格式。只是文件扩展名错误。
    • 正如 ilyas varol 所指出的,您保存的是未修改的 File,而不是已编辑的 image

    打开图片时要记住的基本规则如下:

    要解决未关闭流的问题,您可以改为这样加载图像:

    private void Import_Click(object sender, EventArgs e)
    {
        OpenFileDialog f = new OpenFileDialog();
        f.Filter = "Image files (*.jpg, *.png)|*.jpg;*.png";
        if (f.ShowDialog() != DialogResult.OK)
            return;
        using (Bitmap img = new Bitmap(f.FileName))
        {
            // if a file was already opened, dispose the old one.
            // Start by setting the shown image to null so it
            // will never try to show the disposed object.
            pictureBox1.Image = null;
            if (File != null)
            {
                try { File.Dispose(); }
                catch { /* ignore */ }
            }
            // Clone loaded image into new object
            File = new Bitmap(img);
        }
        pictureBox1.Image = File;
    }
    

    new Bitmap(image) 构造函数是one of the few safe ways to make a clone of an image object that's completely disconnected from the original loaded source。如果之前的颜色格式不同,它确实具有将图像转换为 32 位颜色的副作用。

    不过,这里还有另一个问题。在导出功能中,您再次创建了一个新的Bitmap,但您并未处理。你为什么要克隆?直接使用File 有什么问题吗?如果没有,您应该直接编辑它,并且像素更改也会显示在 UI 上。如果您确实只想将更改应用于保存的图片,请再次为新对象使用 using 块,以便之后自动清理内存中的图像资源。

    此外,您应该只在用户实际确认文件名后才执行该操作。即使他们按下“取消”,您的代码也会执行它,因为它是在您显示对话框之前执行的。

    private void Export_Click(object sender, EventArgs e)
    {
        SaveFileDialog f = new SaveFileDialog();
        f.Filter = "Png Image (.png)|*.png";
        if (f.ShowDialog() != DialogResult.OK)
            return;
        
        // OPTION 1: Edit "File" directly:
    
        // Don't edit without doing the necessary checks.
        if (File.Width > 50 && File.Height > 50)
            File.SetPixel(50, 50, Color.Black);
        File.Save(f.FileName, ImageFormat.Png);
    
        // OPTION 2: Edit clone without affecting "File":
    
        using (Bitmap image = new Bitmap(File))
        {
            // Don't edit without doing the necessary checks.
            if (image.Width > 50 && image.Height > 50)
                image.SetPixel(50, 50, Color.Black);
            image.Save(f.FileName, ImageFormat.Png);
        }
    }
    

    【讨论】:

      【解决方案2】:

      设置颜色操作后,你应该用彩色对象再次设置文件。

      这样;

      image.SetPixel(50, 50, Color.Red);
      File = image;
      

      我希望这对你有用! (我编码并且它对我来说运行正确)

      【讨论】:

      • 或者你应该直接编辑File。或者保存image,而不是File
      猜你喜欢
      • 1970-01-01
      • 2017-09-26
      • 2014-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-20
      • 2020-10-10
      相关资源
      最近更新 更多