如何制作位图的透明背景?

时间:2014-08-30 12:12:16

标签: java android image-processing bitmap bitmapimage

我正在研究一个模块,我必须使位图图像的背景透明。实际上,我正在创建一个像#34;坚持它的应用程序#34;通过它我们可以从任何图像中制作贴纸。我不知道从哪里开始。 有人可以给我一个链接或提示吗?

原始图片 - enter image description here

使背景透明 -

enter image description here

这就是我想要的。

6 个答案:

答案 0 :(得分:1)

我只能提供一些有关如何解决问题的提示。您需要执行图像分段。这可以通过k-means algotithm或类似的聚类算法来实现。有关算法的图像分割算法,请参阅this this以获取Java代码示例。聚类的计算可以在移动设备上非常耗费时间。完成群集后,您可以使用this approach来区分背景和前景。一般来说,你所有的图片应该有一个与前景强烈不同的bachground颜色,否则聚类不可能在它们之间产生干扰。也可能会发生前景中的像素被分配给背景的集群beacuase它具有与背景类似的颜色。为防止这种情况发生,您可以使用this approachregion grwoth algorithm。之后,您可以让用户通过触摸选择群集并将其删除。我的Android应用程序也遇到了同样的问题。这将为您提供一个良好的开端,一旦您实现了custering, 就需要重新设置群集的 k 参数以获得良好的结果。

答案 1 :(得分:0)

似乎是一项艰巨的任务。如果您正在谈论图像处理,如果我理解,那么您可以尝试https://developers.google.com/appengine/docs/java/images/ 此外,如果你想掩盖整个背景(我还没有尝试粘贴)应用程序需要了解背景图像映射。请提供一些示例,以便我能够提出更明确的答案

答案 2 :(得分:0)

如果您在Android中工作,您可能需要一个缓冲区来从图像中获取像素 - 它是一个intBuffer并且它极大地减少了内存使用...从中获取数据并将数据存储到您拥有的缓冲区中三种方法(如果你没有'大图像,你可以跳过那部分):

private IntBuffer buffer;
public void copyImageIntoBuffer(File imgSource) {
    final Bitmap temp = BitmapFactory.decodeFile(imgSource
            .getAbsolutePath());
    buffer.rewind();
    temp.copyPixelsToBuffer(buffer);
}

protected void copyBufferIntoImage(File tempFile) throws IOException {
    buffer.rewind();
    Bitmap temp = Bitmap.createBitmap(imgWidth, imgHeight,
            Config.ARGB_8888);
    temp.copyPixelsFromBuffer(buffer);

    FileOutputStream out = new FileOutputStream(tempFile);
    temp.compress(Bitmap.CompressFormat.JPEG, 90, out);
    out.flush();
    out.close();
}

public void mapBuffer(final File tempFile, long size) throws IOException {

    RandomAccessFile aFile = new RandomAccessFile(tempFile, "rw");
    aFile.setLength(4 * size); // 4 byte pro int
    FileChannel fc = aFile.getChannel();
    buffer = fc.map(FileChannel.MapMode.READ_WRITE, 0, fc.size())
            .asIntBuffer();

}

现在你可以使用Buffer来获取像素并根据需要修改它们...(我复制了一个在我的UI上使用了进度条的代码,因此需要一个Handler / ProgressBar ...我做了这个我正在研究更大的图像并实现了imageFilter(高斯滤波器,灰度滤波器等......只需删除不需要的东西)

public void run(final ProgressBar bar, IntBuffer buffer, Handler mHandler, int imgWidth, int imgHeight, int transparentColor ) {
     for (int dy = 0; dy < imgHeight; dy ++){

        final int progress = (dy*100)/imgHeight;

        for (int dx = 0; dx < imgWidth; dx ++ ){

            int px = buffer.get();
            //int a = (0xFF000000 & px);
            //int r = (0x00FF0000 & px) >> 16;
            //int g = (0x0000FF00 & px) >> 8;
            //int b = (0x000000FF & px);

            //this makes the color transparent
            if (px == transparentColor) {
                px = px | 0xFF000000;
            }


            //r = mid << 16;
            //g = mid << 8;
            //b = mid;
            //int col = a | r | g | b;

            int pos = buffer.position();
            buffer.put(pos-1, px);
        }

        // Update the progress bar
        mHandler.post(new Runnable() {                      
            public void run() {
                bar.setProgress(progress);                          
            }
        });

    }
}

如果你真的有小图片,你可以在onCreate()期间直接获取像素,或者甚至在启动Activity之前更好地创建一个Buffer(可能是HashMap或List)...

答案 3 :(得分:0)

一种可能性是在openCV库中使用floodfill操作。有很多关于如何根据需要进行类似操作的示例和教程,OpenCV已移植到Android。 Google的相关条款当然是“openCV”和“floodfill”。

答案 4 :(得分:0)

对于这种任务(和应用程序),您必须使用openGL。通常在处理openGL时,您将片段着色器基于您在Matlab中构建的模块。一旦你有了片段着色器,就很容易将它应用到图像上。检查this指南如何操作。

这里是link to remove background from image in MatLab

我不熟悉matlab以及它是否可以自己生成GLSL代码(片段着色器)。但即使它没有 - 你可能想要自己学习GLSL,因为坦率地说 - 你正在尝试构建一个图形应用程序,而Android SDK在使用它进行图像处理方面有点短,最重要的是没有强大的硬件 - 它后面的加速引擎 - 我看不出它运作得足够顺畅。

一旦你拥有了人物形象 - 你可以像这样轻松地将它应用于透明背景:

Canvas canvas = new Canvas(canvasBitmap);
canvas.drawColor(Color.TRANSPARENT);   
BitmapDrawable bd = (BitmapDrawable) getResources().getDrawable(R.drawable.loading);    
Bitmap yourBitmap = bd.getBitmap();    
Paint paint = new Paint();    
canvas.drawBitmap(yourBitmap, 0, 0, paint);

答案 5 :(得分:0)

Bitmap newBitmap = Bitmap.createBitmap(image.getWidth(), image.getHeight(),image.getConfig());
Canvas canvas = new Canvas(newBitmap);
canvas.drawColor(Color.TRANSPARENT);
canvas.drawBitmap(image, 0, 0, null);

OR See this

希望这会对你有所帮助