A.Mills
A.Mills

Reputation: 407

Invert Crop from (Cut hole into) Image

Everywhere I look online, I see people posting on how to successfully crop an image. However, I want to 'crop'/ clear a hole out of an image. I want to keep the original image, but crop out a rectangle

enter image description here

As you can see in the image above, I have "cropped" out the kittens face. I maintained the original image, but removed only part of it. I cannot figure out how to do that.

Upvotes: 1

Views: 768

Answers (2)

Medinoc
Medinoc

Reputation: 6608

Setting your Graphics object's CompositingMode property to CompositingMode.SourceCopy will allow your drawing operations to replace the alpha value instead of proportionally opacifying it:

        public static void TestDrawTransparent()
        {
            //This code will, successfully, draw something transparent overwriting an opaque area.
            //More precisely, it creates a 100*100 fully-opaque red square with a 50*50 semi-transparent center.
            using(Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format32bppArgb))
            {
                using(Graphics g = Graphics.FromImage(bmp))
                using(Brush opaqueRedBrush = new SolidBrush(Color.FromArgb(255, 255, 0, 0)))
                using(Brush semiRedBrush = new SolidBrush(Color.FromArgb(128, 255, 0, 0)))
                {
                    g.Clear(Color.Transparent);
                    Rectangle bigRect = new Rectangle(0, 0, 100, 100);
                    Rectangle smallRect = new Rectangle(25, 25, 50, 50);
                    g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy;
                    g.FillRectangle(opaqueRedBrush, bigRect);
                    g.FillRectangle(semiRedBrush, smallRect);
                }
                bmp.Save(@"C:\FilePath\TestDrawTransparent.png", ImageFormat.Png);
            }
        }

In this code, I first draw a fully-opaque red square, then a semi-transparent red square "over" it. The result is a semi-transparent "hole" in the square:

Red square with semi-transparent center And on a black background: The square with semi-transparent hole, on a black background

A zero-opacity brush works just as well, leaving a clear hole through the image (I checked). With that in mind, you should be able to crop any shapes you want, simply by filling them with a zero-opacity brush.

Upvotes: 1

TaW
TaW

Reputation: 54453

Assuming you want to replace the original pixel colors with transparency you run into a small problem: You can't draw or fill with transparency in GDI+.

But you can use Graphics.Clear(Color.Transparent).

To do that you restrict the region where the Graphics object will draw. Here we can use the simple cropping rectangle but you can clear more complex shapes using a GraphicsPath..

Example using a bitmap bmp:

using (Graphics g = Graphics.FromImage(bmp))
{
    Rectangle crop = new Rectangle(222,222,55,55);
    g.SetClip(crop);
    g.Clear(Color.Transparent);
}
bmp.Save(somefilename, ImageFormat.Png);

Upvotes: 4

Related Questions