How to avoid useless white border in PNG resizing with transparent background?

I have a folder containing about 2500 PNG images, without transparency. Each image is about 500 x 500 (some of them 491 x 433, others 511 x 499, etc.).

I want to programmatically reduce the size of each image to 10% of its original size and set the white background of each image as a transparent color.

To test the functionality of my application without resizing 2500 images each time, I used 15 images of billiard balls as a “test” folder.

Now my problem is the following code, I get a modified and cropped PNG that has an almost transparent background. The problem is that the white frame on the left and top is displayed in each image viewer (Irfan View, Paint.Net and GIMP).

How can I avoid this boundary?

Here is the code I used for this:

void ResizeI(string[] Paths, string OutPut, Methods m, PointF Values, bool TwoCheck, bool Overwrite, float[] CropVals)
    {
        for (int i = 0; i < Paths.Length; i++)//Paths is the array of all images
        {
            string Path = Paths[i];//current image
            Bitmap Oimg = (Bitmap)Bitmap.FromFile(Path);//original image
            Bitmap img = new Bitmap((int)(Oimg.Width - CropVals[0] - CropVals[1]), (int)(Oimg.Height - CropVals[2] - CropVals[3]));//cropped image
            Graphics ggg = Graphics.FromImage(img);
            ggg.DrawImage(Oimg, new RectangleF(((float)-CropVals[0]), ((float)-CropVals[2]), Oimg.Width - CropVals[1], Oimg.Height - CropVals[3]));
            ggg.Flush(System.Drawing.Drawing2D.FlushIntention.Flush);
            ggg.Dispose();
            PointF scalefactor = GetScaleFactor(img, Values, TwoCheck);//the scale factor equals 0.1 for 10%
            Bitmap newimg = new Bitmap((int)(Math.Ceiling(((float)img.Width) * scalefactor.X)), (int)(Math.Ceiling(((float)img.Height) * scalefactor.Y)));
            System.Drawing.Imaging.ImageFormat curform = img.RawFormat;
            string OutPath = System.IO.Path.Combine(OutPut, System.IO.Path.GetFileName(Path));
            OutPath = CheckPath(OutPath, Overwrite);//Delete if exsits
            Graphics g = Graphics.FromImage(newimg);
            g.InterpolationMode = GetModeFromMethod(m);//Bicubic interpolation
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.ScaleTransform(scalefactor.X, scalefactor.Y);
            g.DrawImage(img, new Rectangle(0, 0, (int)Math.Ceiling(((float)newimg.Width) / scalefactor.X) + 1, (int)Math.Ceiling(((float)newimg.Height) / scalefactor.Y) + 1));
            //g.Flush(System.Drawing.Drawing2D.FlushIntention.Flush);
            newimg.MakeTransparent(Color.White);
            newimg.Save(OutPath, curform);
            g.Dispose();
            img.Dispose();
        }
    }

And here is an example of a white border that I mentioned. Download the image or drag it and put a black background on it to see the border:

The resized Image and the white border

- EDIT -

I managed to write this function instead of newimg.MakeTransparent(...):

 void SetTransparent(ref Bitmap b)
    {
        for (int i = 0; i < b.Width; i++)
        {
            for (int ii = 0; ii < b.Height; ii++)
            {
                Color cc = b.GetPixel(i, ii);
                int tog = cc.R + cc.G + cc.B;
                float durch = 255f - (((float)tog) / 3f);
                b.SetPixel(i, ii, Color.FromArgb((int)durch, cc.R, cc.G, cc.B));
            }
        }
    }

the problem is that my billiard ball now looks like this:

Second version of the billiard ball

+3
source share
2 answers

I cannot help with the specific code, but maybe I can explain what is happening.

newimg.MakeTransparent(Color.White);

. , () . ( ).

, "" .

, , -, , .net ( , .net).

, , , . , .

UPDATE:

, , , - , , .

, :

  • , - 100% ( X).
  • , , , - ( ).
  • 3px

...

  • X. X, X, 100% .
  • x , .
  • .
  • (a, b, c ..) , / , ( ). , , .
  • , ... , c = 0% b = 33% a = 66%

, , . , , (, ).

, , -.

/. , , , !

+4

SetTransparent , .

:

void SetTransparent(ref Bitmap b)    
{   
    const float selectivity = 20f;  // set it to some number much larger than 1 but less than 255
    for (int i = 0; i < b.Width; i++)
    {        
        for (int ii = 0; ii < b.Height; ii++)
        {
            Color cc = b.GetPixel(i, ii);
            float avgg = (cc.R + cc.G + cc.B) / 3f;
            float durch = Math.Min(255f, (255f - avgg) * selectivity);
            b.SetPixel(i, ii, Color.FromArgb((int)durch, cc.R, cc.G, cc.B));
        }
    }
}

, - , , . , , 0 255, .

, @DA, ( ), . -, .

+1

All Articles