算法是扫描每一行,看看每个像素是否与指定的颜色都一样。都一样则换到下一行再看,否则就从该行起剪裁。
算法是剪裁行,如果剪裁列空白的话可以先把图片旋转90度再按行的方法处理。
颜色容差是必要的,因为如果你是用jeg之类的有损压缩过的图片的话可能会存在肉眼不觉得的失真,但计算机认为这是不同的颜色。
因为用到了指针,在测试的时候需要修改项目属性,允许不安全的代码。
完整代码如下
#region 剪裁掉边框 /// <summary> /// 判断指定行内像素是否与指定颜色都相同 /// </summary> /// <param name="setColor">指定色</param> /// <param name="bmp">原始图</param> /// <param name="lineIndex">行号</param> /// <param name="tolerance">容差</param> /// <returns>是/否</returns> private bool AllPixelsAreSameColor(Color setColor, Bitmap bmp, int lineIndex, int tolerance) { bool rtn = false; int w = bmp.Width; int h = bmp.Height; //取一行 BitmapData data = bmp.LockBits(new Rectangle(0, lineIndex, w, 1), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); unsafe { byte* p = (byte*)data.Scan0; for (int x = 0; x < w; x++) { // 检验指定位置的像素值 Color curColor = Color.FromArgb(p[2],p[1],p[0]); if (ColorIsSimilar(setColor, curColor, tolerance)) { rtn = true; } else { rtn = false; break; } p += 3; } // end of x } bmp.UnlockBits(data); return rtn; } /// <summary> /// 颜色是否近似 /// </summary> /// <param name="c0">颜色0</param> /// <param name="c1">颜色1</param> /// <param name="delta">容差</param> /// <returns>是/否</returns> private bool ColorIsSimilar(Color c0, Color c1, int delta) { int r0, r1, g0, g1, b0, b1; r0 = c0.R; r1 = c1.R; g0 = c0.G; g1 = c1.G; b0 = c0.B; b1 = c1.B; if ((r0 - r1) * (r0 - r1) + (g0 - g1) * (g0 - g1) + (b0 - b1) * (b0 - b1) <= delta * delta) { return true; } else { return false; } } /// <summary> /// 剪裁 /// </summary> /// <param name="b">原始Bitmap</param> /// <param name="StartX">开始坐标X</param> /// <param name="StartY">开始坐标Y</param> /// <param name="iWidth">宽度</param> /// <param name="iHeight">高度</param> /// <returns>剪裁后的Bitmap</returns> private Bitmap KiCut(Bitmap b, int startX, int startY, int iWidth, int iHeight) { if (b == null) { return null; } int w = b.Width; int h = b.Height; if (startX >= w || startY >= h) { return null; } if (startX + iWidth > w) { iWidth = w - startX; } if (startY + iHeight > h) { iHeight = h - startY; } Graphics g = null; try { Bitmap bmpOut = new Bitmap(iWidth, iHeight, PixelFormat.Format24bppRgb); g = Graphics.FromImage(bmpOut); g.DrawImage(b, new Rectangle(0, 0, iWidth, iHeight), new Rectangle(startX, startY, iWidth, iHeight), GraphicsUnit.Pixel); return bmpOut; } catch { return null; } finally { if (g != null) g.Dispose(); } } /// <summary> /// 切除周围的指定颜色 /// </summary> /// <param name="bmp">原始图</param> /// <param name="c">指定色</param> /// <param name="tolerance">颜色容差</param> /// <returns>切除后的图片</returns> public Bitmap CutAround(Bitmap bmp, Color c, int tolerance) { if (bmp == null) return null; bool CutFlag = false; int i = 0; int w = bmp.Width; int h = bmp.Height; // 扫描每一行 for (i = 0; i < h; i++) { // 如果发现此行并非同一个颜色则退出 if (!AllPixelsAreSameColor(c, bmp, i, tolerance)) { CutFlag = true; break; } } // 剪裁 if (CutFlag) bmp = KiCut(bmp, 0, i, w, h - i); return bmp; } #endregion
最新评论
DJ音乐盒 很多无法播放及下载!
什么剧情啊,谁能简单介绍一下?
放电视上用,要输入账号跟密码诶,都是多少啊?
解压码
这是官方更新还是独自更新的?
这个要序列号
大佬能出个去广告的详细点的教程吗。。。本文的去广告介绍我看不太明白。。。
电视上可以用吗