从位图中删除透明绑定

Posted

技术标签:

【中文标题】从位图中删除透明绑定【英文标题】:Remove transparent bound from Bitmap 【发布时间】:2014-06-22 20:51:00 【问题描述】:

我正在研究一种去除位图透明边界的方法。该方法如下所示:

private static final int STEP = 4;//Don't check all the pixel, only a sampling

private Bitmap clipTransparent(Bitmap image) 
    int x1, x2, y1, y2;
    final int width = image.getWidth();
    final int height = image.getHeight();
    for (x1 = 0; x1 < width - 1; x1 += STEP) 
        if (checkColumn(image, x1)) 
            break;
        
    
    x1 = Math.max(0, x1 - STEP);
    for (x2 = width - 1; x2 > x1; x2 -= STEP) 
        if (checkColumn(image, x2)) 
            break;
        
    
    x2 = Math.min(width, x2 + STEP);

    for (y1 = 0; y1 < height - 1; y1 += STEP) 
        if (checkRow(x1, x2, image, y1)) 
            break;
        
    
    y1 = Math.max(0, y1 - STEP);

    for (y2 = height - 1; y2 > 0; y2 -= STEP) 
        if (checkRow(x1, x2, image, y2)) 
            break;
        
    
    y2 = Math.min(height, y2 + STEP);
    try 
        image = Bitmap.createBitmap(image, x1, y1, x2 - x1, y2 - y1);
     catch (Throwable t) 
        t.printStackTrace();
    
    return image;


private boolean checkColumn(Bitmap image, int x1) 
    for (int y = 0; y < image.getHeight(); y += STEP) 
        if (Color.alpha(image.getPixel(x1, y)) > 0) 
            return true;
        
    
    return false;


private boolean checkRow(int x1, int x2, Bitmap image, int y1) 
    for (int x = x1; x < x2; x += STEP) 
        if (Color.alpha(image.getPixel(x, y1)) > 0) 
            return true;
        
    
    return false;

效果很好,但没有我希望的那么快。 代码的瓶颈是获取一个像素的颜色。

现在我通过调用 image.getPixel(x, y) 读取该值,但查看 android 的源代码,getPixel 检查索引并执行其他减慢代码的操作 (x&gt;=0 &amp;&amp; x&lt;getWidth() &amp;&amp; y&gt;=0 &amp;&amp; y&lt;getHeight() &amp;&amp; !isRecycled)...

有没有办法在没有任何索引检查或其他无用的东西(当然在我的情况下没用)的情况下访问像素数据?

PS:我已经尝试使用 getPixels() 返回一个包含所有颜色的 int 数组。但是图像很大,分配所有内存会触发 GC……结果是一个更慢的方法

【问题讨论】:

请看这个解决方案,听起来不错。 This guy remove the bounds of the transparency 【参考方案1】:

根据the docs,您可以将数组传递给getPixels(),以后可以重复使用。这样就不会发生 GC。

【讨论】:

问题是我只需要执行一次操作,并且位图很大(1920x1080)。我没有办法重用一个 2MB 的数组 使用较小的数组并多次调用该方法。

以上是关于从位图中删除透明绑定的主要内容,如果未能解决你的问题,请参考以下文章

画透明位图

从位图和透明度颜色创建蒙版 - Windows GDI

emwin的透明位图

MFC中透明位图原理

透明位图的显示 作者:王骏

如何在Android中从位图中裁剪圆形区域