Hi,
Am just breaking my head over this,
the problem is
to do pixel inversion of an image wen clicked using the button.
for example, if there is a bitmap image which reads 'A', then wen the button is clicked over it on run time, the background shud change to black and the letter A shud be inverted to white.

calling the bitmap image is on runtime.
and button click over it is also run time,
plz let me knw the button click event and the pixel inversion for this problem.

Thanks a lot...

Dani AI

Generated

Three practical ways to invert a bitmap on a button click, depending on the environment and performance needs:

  • Browser (HTML/CSS/JS): use CSS filter: invert(1) for an immediate GPU-accelerated flip, use Canvas getImageData/putImageData for precise per-pixel control, or use WebGL/fragment shaders for large images or repeated work. Note that canvas pixel access requires same-origin/CORS or the draw will be tainted.
  • Desktop (.NET/WinForms): a simple per-pixel loop is easy to understand but can be slow for large images; a color-transform/drawing approach or direct memory access (LockBits/unsafe) will be far faster and more scalable.
  • Tradeoffs: CSS filters are fastest and simplest for a one-off visual invert. Canvas and native pixel ops give exact control (preserve alpha, selective inversion, masks). WebGL and native lock-bit approaches give best throughput for big images or animation.

Example (browser canvas) — the alpha channel is preserved so only RGB values are inverted:

const img = new Image();
img.crossOrigin = 'Anonymous';
img.src = 'image.png';
img.onload = () => {
  const c = document.createElement('canvas');
  c.width = img.naturalWidth; c.height = img.naturalHeight;
  const ctx = c.getContext('2d');
  ctx.drawImage(img, 0, 0);
  const id = ctx.getImageData(0, 0, c.width, c.height);
  const d = id.data;
  for (let i = 0; i < d.length; i += 4) {
    d[i]   = 255 - d[i];     // R
    d[i+1] = 255 - d[i+1];   // G
    d[i+2] = 255 - d[i+2];   // B
  }
  ctx.putImageData(id, 0, 0);
  document.getElementById('targetImg').src = c.toDataURL();
};

Practical notes and troubleshooting:

  • As observed, per-pixel GetPixel/SetPixel is simple but has high overhead; as noted, using a colour-transform/draw call avoids per-pixel managed calls and runs faster. For the best native speed, use LockBits/unsafe or a native accelerated path.
  • For web canvases, ensure images are served with CORS headers (or set crossOrigin = 'Anonymous') before reading pixels.
  • If the goal is "invert the background but keep the character shape" (monochrome letter on background), consider generating a mask (threshold alpha) and composites (difference/xor) rather than a blind full-image invert.
  • Dispose or release large image buffers promptly (Dispose/clear references) to avoid memory pressure in long-running apps.

Recommended Answers

All 3 Replies

This is slow:

private void button1_Click(object sender, EventArgs e)
    {
      Bitmap bmp = (Bitmap.FromFile(@"C:\letter.bmp") as Bitmap);
      pictureBox1.Image = bmp;

      Bitmap bmp2 = (bmp.Clone() as Bitmap);
      for (int x = 0; x < bmp.Width; x++)
      {
        for (int y = 0; y < bmp.Height; y++)
        {
          Color c = bmp2.GetPixel(x, y);
          Color inv = Color.FromArgb(c.A, 255 - c.R, 255 - c.G, 255 - c.B);
          bmp2.SetPixel(x,y,inv);
        }
      }
      pictureBox2.Image = bmp2;
    }

You can also do it with unsafe{} operations. Take a look at:
http://www.vcskicks.com/fast-image-processing.html

Here is another way to do it:

Image img = Image.FromFile(fileName);
            Bitmap bmpInverted = new Bitmap(img.Width, img.Height);
            ImageAttributes ia = new ImageAttributes();
            ColorMatrix cmPicture = new ColorMatrix(new float[][]
            {
                new float[] {-1, 0, 0, 0, 0},
                new float[] {0, -1, 0, 0, 0},
                new float[] {0, 0, -1, 0, 0},
                new float[] {0, 0, 0, 1, 0},
                new float[] {1, 1, 1, 0, 1}
            });
            ia.SetColorMatrix(cmPicture);//cm);
            Graphics g = Graphics.FromImage(bmpInverted);
            g.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel, ia);
            g.Dispose();
            img.Dispose();

            // use the bmpInverted object, which contains the inverted bitmap
            pictureBox1.Image = bmpInverted;

I don't know how the speed compares to sknake's example, but he probably would know.;)

commented: another good way to go about it +14

DdoubleD -- its faster. Anything (including a crayon) is faster than the method I posted. But its using all managed API calls which make some people feel better :P

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.