我有一个包含大约2500个PNG图像的文件夹,没有透明度。每个图像大约500 x 500(有些是491 x 433,其他511 x 499等)。如何避免在透明背景的调整大小的PNG中无用的白色边框?
我想以编程方式将每个图像缩小到其原始大小的10%,并将每个图像的白色背景设置为透明色。
为了测试我的应用程序的功能,而不是每次调整2500张图像的大小,我使用了15张台球图像作为“测试”文件夹。
现在我的问题是与下面的代码,我得到一个调整大小和裁剪PNG,whith 几乎透明背景。问题是每个图像查看器(Irfan View,Paint.Net和GIMP)都出现左边和上边的白色边框
如何避免此边框?
下面是我用这个代码:
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();
}
}
这里是我提到的白色边框的例子。下载图像或拖动它,把一个黑色的背景下,它看到的边界:
- 编辑 -
我设法写这个函数,而不是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));
}
}
}
的问题是,我的台球现在这个样子:
是的,我想到了,但我不知道如何通过.NET访问PNG的Alpha通道?顺便说一句,我的边界看起来像一些控件的3D边框... – alex 2011-06-04 11:32:25
请参阅我的编辑... – alex 2011-06-04 18:07:50
我不知道你可以做到这一点问题。挑战在于,您希望图像外部的白色透明,抗锯齿半透明,以及内部不透明。该脚本将不得不与一个特定的灰色区分开来,这个灰色是黑色抗锯齿边缘的一部分(您希望部分透明)与相同的灰色图像本身的纯色(你想要空白)。让我想一下,我会更新我的答案... – 2011-06-04 20:22:59