Trong 3 năm và không có câu trả lời? Tôi có thể sửa nó.
Như đã nêu trong các chú thích, Bitmap 2 là trong suốt xung quanh các cạnh và ở giữa (chỉ có đường viền ở đó) nên bước đầu tiên là điền vào giữa màu trắng. Có rất nhiều thuật toán lấp đầy lũ lụt có sẵn. Tôi đã sử dụng https://stackoverflow.com/a/8925653/852795 vì nó dễ dàng, mặc dù có những người khác chắc chắn nhanh hơn. Điều này là cần thiết vì nó cho phép bước tiếp theo.
Bước thứ hai là kết hợp Bitmap 2 được lấp đầy với Bitmap 1 bằng cách sử dụng Porter/Duff Composting. PorterDuff.Mode.SRC_ATOP
sẽ sơn Bitmap 1 hiệu quả vào khu vực màu trắng hiện tại của Bitmap 2 trong khi rời khỏi khu vực bên ngoài đường viền trong suốt.
Đây là mã:
package test.testapplication;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.graphics.Bitmap.Config;
import java.util.LinkedList;
import java.util.Queue;
public class MainActivity extends AppCompatActivity {
Bitmap mask, background, filledMask, overlay;
Canvas c;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mask = BitmapFactory.decodeResource(getResources(), R.drawable.mask);
background = BitmapFactory.decodeResource(getResources(), R.drawable.background);
// get the mask, copy it to filledMask and then flood from the center with CYAN
filledMask = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Config.ARGB_8888);
c = new Canvas(filledMask);
c.drawBitmap(mask, 0, 0, new Paint());
Point center = new Point(filledMask.getWidth()/2, filledMask.getHeight()/2);
floodFill(filledMask, center, Color.TRANSPARENT, Color.WHITE);
// create new overlay Bitmap, draw the filledMask and then add the background using PorterDuff
overlay = Bitmap.createBitmap(filledMask.getWidth(), filledMask.getHeight(), Config.ARGB_8888);
c = new Canvas(overlay);
Paint p = new Paint();
p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
c.drawBitmap(filledMask, 0, 0, new Paint());
c.drawBitmap(background, 0, 0, p);
DrawView drawView = new DrawView(this);
// set background to light blue in order to see transparent areas
drawView.setBackgroundColor(0xffd2d7fe);
setContentView(drawView);
drawView.requestFocus();
}
public class DrawView extends View {
Paint p = new Paint();
int top = 0;
public DrawView(Context context) {
super(context);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(mask, 0, 0, p);
top += mask.getHeight();
canvas.drawBitmap(filledMask, 0, top, p);
top += filledMask.getHeight();
canvas.drawBitmap(background, 0, top, p);
top += background.getHeight();
canvas.drawBitmap(overlay, 0, top, p);
}
}
// method from https://stackoverflow.com/a/8925653/852795
public void floodFill(Bitmap bmp, Point pt, int targetColor, int replacementColor) {
Queue<Point> q = new LinkedList<>();
q.add(pt);
while (q.size() > 0) {
Point n = q.poll();
if (bmp.getPixel(n.x, n.y) != targetColor) continue;
Point w = n, e = new Point(n.x + 1, n.y);
while ((w.x > 0) && (bmp.getPixel(w.x, w.y) == targetColor)) {
bmp.setPixel(w.x, w.y, replacementColor);
if ((w.y > 0) && (bmp.getPixel(w.x, w.y - 1) == targetColor)) q.add(new Point(w.x, w.y - 1));
if ((w.y < bmp.getHeight() - 1) && (bmp.getPixel(w.x, w.y + 1) == targetColor)) q.add(new Point(w.x, w.y + 1));
w.x--;
}
while ((e.x < bmp.getWidth() - 1) && (bmp.getPixel(e.x, e.y) == targetColor)) {
bmp.setPixel(e.x, e.y, replacementColor);
if ((e.y > 0) && (bmp.getPixel(e.x, e.y - 1) == targetColor)) q.add(new Point(e.x, e.y - 1));
if ((e.y < bmp.getHeight() - 1) && (bmp.getPixel(e.x, e.y + 1) == targetColor)) q.add(new Point(e.x, e.y + 1));
e.x++;
}
}
}
}
Khi chạy, đầu ra (sau khi thêm một màu xanh nhạt để nền để 'nhìn thấy' các vùng trong suốt của hình ảnh) nên trông như thế này, với những hình ảnh, tương ứng, là Bitmap 2, Bitmap 2 điền, Bitmap 1 và cuối cùng là sự kết hợp của Bitmap 2 điền và Bitmap 1:

có vẻ như một chút 'mờ' chỉ bên trong đường viền , nhưng đó có lẽ một tạo phẩm tràn ngập lũ lụt, hoặc có lẽ là bản gốc Bitmap 2. Chơi xung quanh với cả hai người trong số đó có thể rõ ràng rằng lên.
Điều này có thể được thực hiện và tôi chắc chắn ai đó sẽ ghé qua bằng một số thông tin chi tiết. Nhưng tôi có thể hỏi tại sao bạn không chỉ sử dụng một bitmap hoặc .png của kết quả cuối cùng mà bạn muốn? –
@JadeByfield có lẽ đó là đầu vào và đầu ra động, trong trường hợp này, tốt, bạn không thể làm điều đó – fge
@fge Ahh, điểm tốt :) –