摘要
在某些情况下我们会遇到这样的情况
有一张PNG格式的图片,存在有效像素范围只有红框那么大,其余的像素都是透明的,但是它的实际大小有蓝框那么大,需要对他进行裁剪丢弃掉周围的透明区域,裁剪出一张只有红框范围大小的图片
那么对于少量的图片来说,进行裁剪耗费时间并不算太久,如果现在有很多张这样的图片需要处理,并且每一张图片的尺寸都不相同,那么耗费的时间就很多
因此我通过vs winform制作了一个可以对图片进行批处理的工具
页面介绍
文本框: 用来选择需要处理的文件
执行按钮: 开始批处理
查询按钮: 展示需要处理的文件路径
使用方法
拖拽一个或数个任意类型的文件、文件夹到文本框,会自动获取所有可进行处理的文件,文本框会展示“已获取到x个有效文件”的字样,此时点击查询所有文件可以展示已获取到的所有可以处理文件的路径,或者点击执行以进行批处理操作,操作完成后会在桌面生成Res文件夹,所有处理好的文件位于该文件夹内。
PS:仅支持windows系统、在拖拽文件后不进行操作而是重新拖拽新的文件,会清空上次所拖拽的文件、可以操作的类型有png和jpg,但是对jpg操作没作用,因为jpg本身就没有透明通道
核心代码
private void DisposeImage(string imagePath,string outputPath)
{
outputPath += @"\" + Path.GetFileName(imagePath);
using (Bitmap bitmap = new Bitmap(imagePath))
{
// 锁定位图的整个区域
Rectangle rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
BitmapData bitmapData = bitmap.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
// 初始化边界值
int left = bitmap.Width;
int top = bitmap.Height;
int right = 0;
int bottom = 0;
unsafe // 使用unsafe代码块来处理指针
{
// 获取位图数据的首地址
byte* ptrFirstPixel = (byte*)bitmapData.Scan0;
// 遍历所有像素来寻找边界
for (int y = 0; y < bitmap.Height; y++)
{
byte* currentLine = ptrFirstPixel + (y * bitmapData.Stride);
for (int x = 0; x < bitmap.Width; x++)
{
// 获取像素的Alpha值
byte alpha = currentLine[x * 4 + 3];
// 如果像素不完全透明,则更新边界值
if (alpha != 0)
{
if (x < left) left = x;
if (x > right) right = x;
if (y < top) top = y;
if (y > bottom) bottom = y;
}
}
}
}
// 解锁位图
bitmap.UnlockBits(bitmapData);
// 创建裁剪矩形
Rectangle cropRect = new Rectangle(left, top, right - left + 1, bottom - top + 1);
// 使用裁剪矩形创建裁剪后的图片
using (Bitmap croppedBitmap = new Bitmap(cropRect.Width, cropRect.Height))
{
using (Graphics g = Graphics.FromImage(croppedBitmap))
{
g.DrawImage(bitmap, new Rectangle(0, 0, croppedBitmap.Width, croppedBitmap.Height), cropRect, GraphicsUnit.Pixel);
}
// 保存裁剪后的图片
croppedBitmap.Save(outputPath, ImageFormat.Png);
}
}
}
源文件
百度云
链接:https://pan.baidu.com/s/1gzvlUx_i6jcbnBk3OepoCA?pwd=n19i
提取码:n19i