如果有一个透明的png图像,譬如下图这个图片除了中间有两个彩色的圆外,其余部分都是透明。如何在程序中自动剪裁成一个最小的长方形,这个长方形里面包含这两个彩色的圆,其余部分剪裁掉。同时得到剪裁后长方形的长与宽,以及得到这个长方形的左上角相当于原图的坐标。
解决方案 »
- C#中,webbrowser打开多个网站,关闭后会出现咚咚的声音
- 泛类实现表的筛选 功能
- 100分求购聊天室程序源码!
- ArrayList怎么快速去掉重复项?
- C# WinForm中,关于DataGrid批量删除的问题,请教高手!
- 用.net写过C/S的各位大哥请进!
- 请教在datagrid中如何把某一列的字段显示成其它数据?如1显示a,2显示成b?
- 请教高手,如何在c#或vb.net里调用c++ 写的函数?
- 如何获得所播放的MP3文件的长度啊?我用MEDIA PLAY控件,谢谢.
- 使用C#编写区块链程序调用Nbitcoin.dll时出现系统无效操作异常
- winfrom POST提交一个数据包时候出现411错误
- 这个集合怎么处理
如果考虑旋转,稍微复杂点,首先求出所有点x y的平均值,这是重心。以此为基准,求出这些点到重心的距离取得最大值,以这个点和重心的连线为基准将图像旋转,再按照前述的方法计算。
ExitFlag = False
If Top = True Then '¶¥²¿
For Y = 0 To m_Height - 1
If ExitFlag = True Then Exit For
Speed = m_Stride * Y
For X = 0 To m_Width - 1
If ImageData(Speed) <> Blue Or ImageData(Speed + 1) <> Green Or ImageData(Speed + 2) <> Red Or ImageData(Speed + 3) <> Alpha Then
TopPos = Y
ExitFlag = True
Exit For
End If
Speed = Speed + 4
Next
Next
End If ExitFlag = False
If Left = True Then '×ó²¿
For X = 0 To m_Width - 1
If ExitFlag = True Then Exit For
Speed = X * 4
For Y = 0 To m_Height - 1
If ImageData(Speed) <> Blue Or ImageData(Speed + 1) <> Green Or ImageData(Speed + 2) <> Red Or ImageData(Speed + 3) <> Alpha Then
LeftPos = X
ExitFlag = True
Exit For
End If
Speed = Speed + m_Stride
Next
Next
End If
ExitFlag = False
If Bottom = True Then 'µ×²¿
For Y = m_Height - 1 To 0 Step -1
If ExitFlag = True Then Exit For
Speed = m_Stride * Y
For X = 0 To m_Width - 1
If ImageData(Speed) <> Blue Or ImageData(Speed + 1) <> Green Or ImageData(Speed + 2) <> Red Or ImageData(Speed + 3) <> Alpha Then
BottomPos = Y
ExitFlag = True
Exit For
End If
Speed = Speed + 4
Next
Next
End If
ExitFlag = False
If Right = True Then 'ÓÒ²¿
For X = m_Width - 1 To 0 Step -1
If ExitFlag = True Then Exit For
Speed = X * 4
For Y = 0 To m_Height - 1
If ImageData(Speed) <> Blue Or ImageData(Speed + 1) <> Green Or ImageData(Speed + 2) <> Red Or ImageData(Speed + 3) <> Alpha Then
RightPos = X
ExitFlag = True
Exit For
End If
Speed = Speed + m_Stride
Next
Next End If
以上就得到了要修整的区域的坐标,下面就是要复制图像数据的程序了。
在你这里就是指alpha通道不是透明,颜色不是0xFFFFFF的。
For X = 0 To m_Width - 1
足矣“吓死人”啦。对于任意点,取最大的X值、最小的X值、最大的Y值、最小的Y值就行了。不要“更技术”的任何方法。
/// <summary>
/// 去除白边
/// </summary>
/// <param name="bm"></param>
/// <returns></returns>
public static Bitmap ClearWhite(Bitmap bm)
{
int y_l = 0;//左边
int y_r = 0;//右边
int i_h = 0;//上边
int i_d = 0;//下边
#region 计算----
for (int i = 0; i < bm.Width; i++)
{
for(int y=0;y<bm.Height;y++)
{
if (bm.GetPixel(i, y).R != 255 || bm.GetPixel(i, y).B != 255 || bm.GetPixel(i, y).G != 255)
{
y_l = i;
goto yl;
}
}
}
yl:
for (int i = 0; i < bm.Width; i++)
{
for (int y = 0; y < bm.Height; y++)
{
if (bm.GetPixel(bm.Width - i - 1, y).R != 255 || bm.GetPixel(bm.Width - i - 1, y).B != 255 || bm.GetPixel(bm.Width - i - 1, y).G != 255)
{
y_r = i;
goto yr;
}
}
}
yr:
for (int i = 0; i < bm.Height; i++)
{
for (int y = 0; y < bm.Width; y++)
{
if (bm.GetPixel(y, i).R != 255 || bm.GetPixel(y, i).B != 255 || bm.GetPixel(y, i).G != 255)
{
i_h = i;
goto ih;
}
}
}
ih:
for (int i = 0; i < bm.Height; i++)
{
for (int y = 0; y < bm.Width; y++)
{
if (bm.GetPixel(y, bm.Height - i - 1).R != 255 || bm.GetPixel(y, bm.Height - i - 1).B != 255 || bm.GetPixel(y, bm.Height - i - 1).G != 255)
{
i_d = i;
goto id;
}
}
}
id:
#endregion //创建此大小的图片
Bitmap bmp = new Bitmap(bm.Width - y_l - y_r, bm.Height - i_h - i_d);
Graphics g = Graphics.FromImage(bmp);
//(new Point(y_l, i_h), new Point(0, 0), new Size(bm.Width - y_l - y_r, bm.Height - i_h - i_d));
Rectangle sourceRectangle = new Rectangle(y_l, i_h, bm.Width - y_l - y_r, bm.Height - i_h - i_d);
Rectangle resultRectangle = new Rectangle(0, 0, bm.Width - y_l - y_r, bm.Height - i_h - i_d);
g.DrawImage(bm, resultRectangle, sourceRectangle, GraphicsUnit.Pixel);
g.Dispose();
return bmp;
}以前写的。各位别笑 - -
我有方法你自己改改
是否Speed$(0xf)检测更高效?