[英]How can I make transparent background of a Bitmap?
我正在開發一個模塊,其中必須使位圖圖像的背景透明。 實際上,我正在制作一個像“ Stick it”這樣的應用程序,通過它我們可以在任何圖像上制作貼紙。 我不知道從哪里開始。 有人可以給我鏈接或提示嗎?
原始圖片-
使背景透明后
這就是我要的。
我只能提供一些有關如何解決您的問題的提示。 您需要執行圖像分割 。 這可以通過k均值算法或類似的聚類算法來實現。 見這 對通過聚類圖像segmantation和算法 這對於一個Java代碼示例。 聚類的計算在移動設備上可能非常耗時。 一旦有了群集,就可以使用這種方法來區分背景和前景。 通常,所有圖片應具有與前景強烈不同的背景色,否則,群集之間就不會混淆。 也有可能發生,因為您的前景內部的像素與背景具有相似的顏色,因此將其分配給背景的群集。 為了防止這種情況的發生,您可以使用這種方法或區域增長算法 。 之后,您可以讓用戶通過觸摸選擇集群並將其刪除。 我的Android應用程序也有同樣的問題。 這將為您提供一個良好的開始,並且一旦實施了誘捕程序,您只需要調整聚類的k參數即可獲得良好的結果。
似乎是一項艱巨的任務。 如果您說的是我可能理解的圖像處理,那么可以嘗試https://developers.google.com/appengine/docs/java/images/另外,如果您想遮蓋整個背景(我還沒有嘗試過粘貼)應用程序需要了解背景圖像圖。 請提供一些示例,以便我得出更明確的答案
如果您在Android上工作,則可能需要一個Buffer來從圖像中獲取像素-這是一個intBuffer,它極大地減少了內存使用...要從Buffer中獲取數據或將數據存儲到Buffer中,您可以使用以下三種方法(您可以跳過如果您沒有“大”圖像,則該部分):
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)。
一種可能性是利用openCV庫中的Floodfill操作。 關於如何做與您想要的東西類似的事情,有很多示例和教程,並且OpenCV已移植到Android。 Google的相關術語當然是“ openCV”和“ floodfill”。
對於此類任務(和應用程序),您必須使用openGL。 通常,在使用openGL時,您的片段着色器基於在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);
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);
或看到這個
希望這會幫助你
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.