【发布时间】:2017-09-09 02:36:18
【问题描述】:
我正在使用以下代码来删除图像周围的空白。
static Bitmap TrimBitmap(Bitmap source)
{
Rectangle srcRect = default(Rectangle);
BitmapData data = null;
try
{
data = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
byte[] buffer = new byte[data.Height * data.Stride];
Marshal.Copy(data.Scan0, buffer, 0, buffer.Length);
int xMin = int.MaxValue,
xMax = int.MinValue,
yMin = int.MaxValue,
yMax = int.MinValue;
bool foundPixel = false;
// Find xMin
for (int x = 0; x < data.Width; x++)
{
bool stop = false;
for (int y = 0; y < data.Height; y++)
{
byte alpha = buffer[y * data.Stride + 4 * x + 3];
if (alpha != 0)
{
xMin = x;
stop = true;
foundPixel = true;
break;
}
}
if (stop)
break;
}
// Image is empty...
if (!foundPixel)
return null;
// Find yMin
for (int y = 0; y < data.Height; y++)
{
bool stop = false;
for (int x = xMin; x < data.Width; x++)
{
byte alpha = buffer[y * data.Stride + 4 * x + 3];
if (alpha != 0)
{
yMin = y;
stop = true;
break;
}
}
if (stop)
break;
}
// Find xMax
for (int x = data.Width - 1; x >= xMin; x--)
{
bool stop = false;
for (int y = yMin; y < data.Height; y++)
{
byte alpha = buffer[y * data.Stride + 4 * x + 3];
if (alpha != 0)
{
xMax = x;
stop = true;
break;
}
}
if (stop)
break;
}
// Find yMax
for (int y = data.Height - 1; y >= yMin; y--)
{
bool stop = false;
for (int x = xMin; x <= xMax; x++)
{
byte alpha = buffer[y * data.Stride + 4 * x + 3];
if (alpha != 0)
{
yMax = y;
stop = true;
break;
}
}
if (stop)
break;
}
srcRect = Rectangle.FromLTRB(xMin, yMin, xMax , yMax);
}
finally
{
if (data != null)
source.UnlockBits(data);
}
Bitmap dest = new Bitmap(srcRect.Width, srcRect.Height);
Rectangle destRect = new Rectangle(0, 0, srcRect.Width, srcRect.Height);
using (Graphics graphics = Graphics.FromImage(dest))
{
graphics.DrawImage(source, destRect, srcRect, GraphicsUnit.Pixel);
}
return dest;
}
我正在尝试修剪一个带有文本绘制的位图。修剪后正确的图像应该是这样的
但修剪后我得到以下结果..底部被剪掉
我做错了什么?请指教。。
【问题讨论】:
-
你展示的图片让我很困惑。任何 alpha == 0 在哪里?结果是哪一部分?只是红色盒子里面的部分??您假设 a==0 或 == 255 可能是错误的边界清晰,并且您有半透明像素..很难从图像中分辨出来。也许阈值比测试 0 更有效。
-
@TaW 我已经绘制了红色框以显示底部文本的剪切.. 例如比较第一张和第二张图片中的
s。另外我正在绘制这个文本一个单独的图像(new Bitmap(somewidth,someheight))并在另一个图像上绘制文本位图。 -
@TaW hmm.. 好的.. 你能更新代码并为我回答吗?
-
试试这个:
srcRect = Rectangle.FromLTRB(xMin, yMin, xMax-xMin , yMax-yMin); -
@TaW 此更新导致图像的一半被切割.. 要清楚.. 上面的代码用于修剪图像周围的白色部分/空白区域(左、右、顶部和底部)..