Подтвердить что ты не робот

Android, как применить маску к ImageView?

Итак, я попробовал код здесь: Создание ImageView с маской. Я использую следующие изображения в качестве оригинала и маски:

enter image description hereenter image description here

Однако я получаю результат:

enter image description here

Обратите внимание, что фон фона не черный, но голосный свет (который на галактике nexus выглядит очень бледно-серым, а не совсем белым). Второе изображение - результат, который я получаю, когда элемент выбран в виде списка.

Если вместо этого я создаю новый битмап, используя тот же алгоритм, а затем передаю его в представление изображения вместо переопределения onDraw(), он рисует правильно:

Canvas canvas = new Canvas();
Bitmap mainImage = //get original image
Bitmap maskImage = //get mask image
Bitmap result = Bitmap.createBitmap(mainImage.getWidth(), mainImage.getHeight(), Bitmap.Config.ARGB_8888);

canvas.setBitmap(result);
Paint paint = new Paint();
paint.setFilterBitmap(false);

canvas.drawBitmap(mainImage, 0, 0, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
canvas.drawBitmap(maskImage, 0, 0, paint);
paint.setXfermode(null);

imageView.setImageBitmap(result);

Я получаю ожидаемый результат:

enter image description here

Обратите внимание на правильное применение затухания. Это более очевидно при выборе.

Итак, что происходит в методе ImageView onDraw для создания этого черного фона вместо того, чтобы пропускать окно фона? Интересно, что если само исходное изображение имеет некоторую прозрачность, то прозрачность соблюдается, например:

enter image description here

Я не могу понять это сам. Я предпочел бы сделать это на onDraw вместо предварительного создания растрового изображения, потому что он работает только для растровых изображений в качестве источника и маски. Я хочу иметь возможность делать это с другими чертежами, такими как градиенты и сплошные цвета, но в этих случаях ширина и высота не заданы.

4b9b3361

Ответ 1

Я нашел идеальную комбинацию для создания маскировки без черной границы после исследования через все столбцы stackoverflow. Это хорошо подходит моей цели.

В настоящее время я создаю перетаскиваемый вид, используя одно нормальное изображение и маскирующее изображение (png с прозрачностью), поэтому мне нужно переопределить функцию onDraw.

private Bitmap mImage = ...;
private Bitmap mMask = ...;  // png mask with transparency
private int mPosX = 0;
private int mPosY = 0;

private final Paint maskPaint;
private final Paint imagePaint;

public CustomView (final Context context) {
    maskPaint = new Paint();
    maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));

    imagePaint = new Paint();
    imagePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OVER));
}

/* TODO
 if you have more constructors, make sure you initialize maskPaint and imagePaint
 Declaring these as final means that all your constructors have to initialize them.
 Failure to do so = your code won't compile.
*/

@Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    canvas.save();      
    canvas.drawBitmap(mMask, 0, 0, maskPaint);
    canvas.drawBitmap(mImage, mPosX, mPosY, imagePaint);
    canvas.restore();
}

Ответ 2

Отвечая на мой вопрос. Xfermode работал по назначению. Краска создавала прозрачность холста (который был холстом, используемым активностью окна). Поскольку сам холст был установлен прозрачным, в окне показывалось, что было за ним: черный фон.

Чтобы сделать это правильно, действительно необходимо создать новый битмап, чтобы сохранить результат альфа-маски. Я обновил код, чтобы принимать во внимание чертежи всех типов.

Ответ 3

В этом коде Применить:

 mask_over = BitmapFactory.decodeResource(
            getResources(), mask_over1[0]);
    icon = Bitmap.createScaledBitmap(icon, screenwidth, screenwidth, false);
    mask_over = Bitmap.createScaledBitmap(mask_over, screenwidth, screenwidth, false);
             back_img=createBitmap_ScriptIntrinsicBlur(Bitmap.createScaledBitmap(cropview.croppedImage, screenwidth, screenwidth, false),25.0f);
    LinearLayout.LayoutParams layoutParams111 = new LinearLayout.LayoutParams(screenwidth, screenwidth);