-1
  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);
            }
        }
    }

What I want to do is to import an image, change the color of a pixel of it, and export it.

What am I doing wrong? Thanks in advance.

Apple Pie
  • 11
  • 5

2 Answers2

2

After Setting color operation, you should set File again with colored object.

That way;

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

I hope this works for you! (I coded and it runs correctly for me)

ilyas varol
  • 788
  • 3
  • 10
  • 25
2

There are actually several issues with your code:

  • You're not closing the file stream of the image you opened, meaning you will never be able to save the modified image to the same filename. In fact, no program will be able to overwrite the file until your program is closed.
  • You don't check if the edit is possible; open an image that is less than 51 pixels in either dimension and the save operation will crash.
  • You're only offering to save as jpeg... a format in which a single pixel change will inevitably be smudged by the compression.
  • You're not actually saving as jpeg. The default save without specifying a type will make the image end up as png format. It'll just have the wrong file extension.
  • As ilyas varol pointed out, you're saving the unmodified File instead of the edited image.

The basic rules to remember when opening images are these:

To get around the problem of the unclosed stream, you can load the image like this instead:

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;
}

The new Bitmap(image) constructor is one of the few safe ways to make a clone of an image object that's completely disconnected from the original loaded source. It does have the side effect of converting the image to 32-bit colour, if it was in a different colour format before.

There's another issue here, though. In the export function, you are once again making a new Bitmap that you do not dispose. Why do you make that clone? Is there any issue with using File directly? If there isn't, you should just edit it directly, and the pixel change will be shown on the UI as well. If you do want to only apply the change to the saved picture, again, use a using block for the new object, so the image resources in memory are cleaned up automatically afterwards.

Also, you should really only perform the operation once the user has actually confirmed the filename. Your code performs it even if they press "Cancel", because it's performed before you even show the dialog.

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);
    }
}
Nyerguds
  • 5,360
  • 1
  • 31
  • 63