2013-09-26 51 views
3

我有一个关于Android中的位图的问题:我有一个位图,白色边距[大小未知]左右。是否可以创建一个删除了所有白色边距(矩形形状)的新位图?Android位图删除白边

Bitmap bmp = Bitmap.createBitmap(width, bmpheigth, Config.ARGB_8888); 
    Canvas canvas = new Canvas(bmp); 
    canvas.setBitmap(bmp); 
    canvas.drawColor(Color.WHITE); 
// draw here things! 

这是假定未知的东西在哪里画。

什么是一个很好的方法来做到这一点? 谢谢!

回答

2

使用Bitmap.createBitmap(source, x, y, width, height)所以知道白色边距的大小,你可以做你想做的。

+0

其实我不知道保证金的大小(例如canvas.drawText与字母[用户输入]未知的数字,我在寻找一种方法来检测和删除边距.->创建新的位图 – user1616685

+0

@ user1616685有一点复杂但可用的过程 - 获取具有边距的位图,然后只是遍历每边的边界像素,直到找到没有白色的像素 - 这是边距末端,实际上这样做给你所有的利润,然后你可以使用我上面描述的方法 –

+0

循环位图像素?http://developer.android.com/reference/android/graphics/Bitmap.html#getPixels%28int [],%20int,%20int,%20int,%20int,%20int,%20int%29我会试试看在这里它 – user1616685

5

感谢@Maxim叶菲莫夫& @StackOverflowException

,以防万一有人需要一个片断的这样那样的问题:

这个方法返回删除了利润率切出更小的位图。首先将像素传递给int数组,然后使用该数组比Bitmap.getPixel方法快一点

只调用指示源位图和背景色的方法。

Bitmap bmp2 = removeMargins(bmp, Color.WHITE); 


private static Bitmap removeMargins2(Bitmap bmp, int color) { 
    // TODO Auto-generated method stub 


    long dtMili = System.currentTimeMillis(); 
    int MTop = 0, MBot = 0, MLeft = 0, MRight = 0; 
    boolean found1 = false, found2 = false; 

    int[] bmpIn = new int[bmp.getWidth() * bmp.getHeight()]; 
    int[][] bmpInt = new int[bmp.getWidth()][bmp.getHeight()]; 

    bmp.getPixels(bmpIn, 0, bmp.getWidth(), 0, 0, bmp.getWidth(), 
      bmp.getHeight()); 

    for (int ii = 0, contX = 0, contY = 0; ii < bmpIn.length; ii++) { 
     bmpInt[contX][contY] = bmpIn[ii]; 
     contX++; 
     if (contX >= bmp.getWidth()) { 
      contX = 0; 
      contY++; 
      if (contY >= bmp.getHeight()) { 
       break; 
      } 
     } 
    } 

    for (int hP = 0; hP < bmpInt[0].length && !found2; hP++) { 
     // looking for MTop 
     for (int wP = 0; wP < bmpInt.length && !found2; wP++) { 
      if (bmpInt[wP][hP] != color) { 
       Log.e("MTop 2", "Pixel found @" + hP); 
       MTop = hP; 
       found2 = true; 
       break; 
      } 
     } 
    } 
    found2 = false; 

    for (int hP = bmpInt[0].length - 1; hP >= 0 && !found2; hP--) { 
     // looking for MBot 
     for (int wP = 0; wP < bmpInt.length && !found2; wP++) { 
      if (bmpInt[wP][hP] != color) { 
       Log.e("MBot 2", "Pixel found @" + hP); 
       MBot = bmp.getHeight() - hP; 
       found2 = true; 
       break; 
      } 
     } 
    } 
    found2 = false; 

    for (int wP = 0; wP < bmpInt.length && !found2; wP++) { 
     // looking for MLeft 
     for (int hP = 0; hP < bmpInt[0].length && !found2; hP++) { 
      if (bmpInt[wP][hP] != color) { 
       Log.e("MLeft 2", "Pixel found @" + wP); 
       MLeft = wP; 
       found2 = true; 
       break; 
      } 
     } 
    } 
    found2 = false; 

    for (int wP = bmpInt.length - 1; wP >= 0 && !found2; wP--) { 
     // looking for MRight 
     for (int hP = 0; hP < bmpInt[0].length && !found2; hP++) { 
      if (bmpInt[wP][hP] != color) { 
       Log.e("MRight 2", "Pixel found @" + wP); 
       MRight = bmp.getWidth() - wP; 
       found2 = true; 
       break; 
      } 
     } 

    } 
    found2 = false; 

    int sizeY = bmp.getHeight() - MBot - MTop, sizeX = bmp.getWidth() 
      - MRight - MLeft; 

    Bitmap bmp2 = Bitmap.createBitmap(bmp, MLeft, MTop, sizeX, sizeY); 
    dtMili = (System.currentTimeMillis() - dtMili); 
    Log.e("Margin 2", 
      "Time needed " + dtMili + "mSec\nh:" + bmp.getWidth() + "w:" 
        + bmp.getHeight() + "\narray x:" + bmpInt.length + "y:" 
        + bmpInt[0].length); 
    return bmp2; 
} 
+1

我认为你正在修剪1像素太多,因为你只在下一次迭代时退出外部循环。我想你应该测试例如'wP> -1 &&!found2' – njzk2

+1

这是什么表现?它看起来像批量获取所有像素可能会加快这个很多... – tilpner

+0

我用它在一个设备和一个500x700位图我需要180mSec,但它是一个1.2 GHz的处理器。你有更快的解决方案吗?你能给一个片段吗? – user1616685

0

我的解决办法:

private Bitmap trim(Bitmap bitmap, int trimColor){ 
     int minX = Integer.MAX_VALUE; 
     int maxX = 0; 
     int minY = Integer.MAX_VALUE; 
     int maxY = 0; 

     for(int x = 0; x < bitmap.getWidth(); x++){ 
      for(int y = 0; y < bitmap.getHeight(); y++){ 
       if(bitmap.getPixel(x, y) != trimColor){ 
        if(x < minX){ 
         minX = x; 
        } 
        if(x > maxX){ 
         maxX = x; 
        } 
        if(y < minY){ 
         minY = y; 
        } 
        if(y > maxY){ 
         maxY = y; 
        } 
       } 
      } 
     } 
     return Bitmap.createBitmap(bitmap, minX, minY, maxX - minX + 1, maxY - minY + 1); 
    } 

这不是非常快,1280×576像素的位图执行了对小蜜红米手机3S 2965ms。 如果可能的规模缩小图像的修边前:

private Bitmap scaleDown(Bitmap bitmap, float maxImageSize, boolean filter) { 
     float ratio = Math.min(maxImageSize/bitmap.getWidth(), maxImageSize/bitmap.getHeight()); 
     int width = Math.round(ratio * bitmap.getWidth()); 
     int height = Math.round(ratio * bitmap.getHeight()); 

     return Bitmap.createScaledBitmap(bitmap, width, height, filter); 
    }