2011-10-12 37 views
8

Tôi đang cố gắng kết hợp hai hình ảnh cùng với Android, sử dụng chế độ hòa trộn giống như Multiply.Trộn hai hình ảnh cùng với nhân và% opacity

// Prepare ------------------------------- 

// Create source images 
Bitmap img1 = ... 
Bitmap img2 = ... 

// Create result image 
Bitmap result = ... 
Canvas canvas = new Canvas(); 
canvas.setBitmap(result); 

// Get proper display reference 
BitmapDrawable drawable = new BitmapDrawable(getResources(), result); 
ImageView imageView = (ImageView)findViewById(R.id.imageBlend1); 
imageView.setImageDrawable(drawable); 


// Apply ------------------------------- 

// Draw base 
canvas.drawBitmap(img1, 0, 0, null); 

// Draw overlay 
Paint paint = new Paint(); 
paint.setXfermode(new PorterDuffXfermode(Mode.MULTIPLY)); 
paint.setShader(new BitmapShader(img2, TileMode.CLAMP, TileMode.CLAMP)); 

canvas.drawRect(0, 0, img2.getWidth(), img2.getHeight(), paint); 

Điều này có tác dụng, nhưng tôi không kiểm soát được "số tiền" nhân được thực hiện - nó luôn là một chuyển hoàn toàn. Lý tưởng nhất, một 0% nhân sẽ giống như hình ảnh cơ sở (img1) mà không có bất kỳ thay đổi nào, nhưng 100% nhân sẽ là kết quả tôi nhận được với mã ở trên.

paint.setAlpha() dường như không hoạt động cho việc này.

Bất kỳ cách nào khác để đặt độ mờ% của lớp 'mới'?

P.S. Có một số phương pháp để làm cho nhân làm việc với điều này tôi đoán (bằng cách sử dụng một LightingColorFilter) bằng cách nhân trước và bù đắp màu trắng, nhưng nó rất cụ thể cho multiplymode .. Tôi đang cố gắng tìm một cách để áp dụng opacity/% điều cho tất cả các chế độ truyền khác.

Trả lời

2

Tôi cần làm điều gì đó như vậy trong khi trước đây và tôi thấy this post about Color Channels rất nhiều sự khai sáng. (Nhưng tôi sợ điều này liên quan đến những gì bạn mô tả trong "PS")

+1

Valeu rapaz. Nhưng vâng, bài viết rất hay, nhưng nó chỉ là nhiều hơn về việc gắn các lớp với các chế độ khác nhau hơn là có cách thay đổi% giá trị đầu vào cho mỗi chế độ. Nó cho thấy một số thao tác trực tiếp của các điểm ảnh sau khi đọc chúng từ hình ảnh, vì vậy có lẽ nó là một thay thế. Tôi sẽ cần phải điều tra điều đó. Bây giờ, cảm ơn! – zeh

+1

Không tìm thấy liên kết, bro. Vui lòng cập nhật! –

2

Tôi đã triển khai bộ lọc ảnh tương tự như ứng dụng iOS của chúng tôi. Họ làm điều gì đó như source bitmap + mask bitmap + blend mode + alpha value. Để đạt được hành vi giống hệt nhau, tôi chỉ tăng alpha mặt nạ. Dưới đây là những gì mã của tôi cuối cùng trông:

public static Bitmap blend(Bitmap back, Bitmap front, BlendMethod method, float alpha) { 
    if (alpha != 1.0F) { 
     front = makeTransparent(front, Math.round(alpha * 255)); 
    } 

    Bitmap.Config config = back.getConfig(); 
    int width = back.getWidth(); 
    int height = back.getHeight(); 

    if (width != front.getWidth() || height != front.getHeight()) { 
     Log.e(TAG, "Arrays must be of identical size! Do bitmap scaling prior to blending."); 
     return null; 
    } 

    int[] frontArr = new int[height * width], backArr = new int[height * width], resultArr; 

    back.getPixels(backArr, 0, width, 0, 0, width, height); 
    front.getPixels(frontArr, 0, width, 0, 0, width, height); 

    resultArr = jniBlend(frontArr, backArr, alpha, method.toInt()); 
    return Bitmap.createBitmap(resultArr, width, height, config); 
} 

public static Bitmap blend(Bitmap back, Bitmap front, BlendMethod method) { 
    return blend(back, front, method, 1F); 
} 

public static Bitmap makeTransparent(Bitmap src, int value) { 
    int width = src.getWidth(); 
    int height = src.getHeight(); 
    Bitmap transBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
    Canvas canvas = new Canvas(transBitmap); 
    canvas.drawARGB(0, 0, 0, 0); 
    // config paint 
    final Paint paint = new Paint(); 
    paint.setAlpha(value); 
    canvas.drawBitmap(src, 0, 0, paint); 
    return transBitmap; 
} 

Lưu ý rằng jniBlend là một số phương pháp tôi tự viết, nó hoạt động giống như chế độ kho PorterDuff trong Java.

Phương pháp makeTransparent không phải của tôi - tìm thấy nó here: (câu trả lời từ Ruban)

0

Mã này là chưa đầy đủ. nó chỉ là cung cấp cho bạn một ý tưởng để bạn có thể sử dụng tập lệnh hiển thị để pha trộn hình ảnh

public Bitmap blend(Bitmap image) 
{ 
    final float BLUR_RADIUS = 25f; 
    Bitmap outbitmap = Bitmap.createBitmap(image); 
    final RenderScript renderScript = RenderScript.create(this); 

    Allocation tmpin = Allocation.createFromBitmap(renderScript,image); 
    Allocation tmpout = Allocation.createFromBitmap(renderScript,outbitmap); 
    ScriptIntrinsicBlend blend = ScriptIntrinsicBlend.create(renderScript, 
    Element.U8_4(renderScript)); 

    blend.forEachMultiply(tmpin,tmpout); 
    return outbitmap; 
} 
Các vấn đề liên quan