Цвет растровой маски Android, удалить цвет - PullRequest
9 голосов
/ 22 июня 2011

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

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

Ответы [ 3 ]

13 голосов
/ 27 июня 2011

Это работает для удаления определенного цвета из растрового изображения. Основная часть - это использование AvoidXfermode. Это также должно работать, если вы пытаетесь изменить один цвет на другой.

Я должен добавить, что это отвечает на заголовок вопроса об удалении цвета из растрового изображения. Конкретный вопрос, вероятно, лучше решить с помощью PorterDuff Xfermode, как сказано в OP.

// start with a Bitmap bmp

// make a mutable copy and a canvas from this mutable bitmap
Bitmap mb = bmp.copy(Bitmap.Config.ARGB_8888, true);
Canvas c = new Canvas(mb);

// get the int for the colour which needs to be removed
Paint p = new Paint();
p.setARGB(255, 255, 0, 0); // ARGB for the color, in this case red
int removeColor = p.getColor(); // store this color's int for later use

// Next, set the alpha of the paint to transparent so the color can be removed.
// This could also be non-transparent and be used to turn one color into another color            
p.setAlpha(0);

// then, set the Xfermode of the pain to AvoidXfermode
// removeColor is the color that will be replaced with the pain't color
// 0 is the tolerance (in this case, only the color to be removed is targetted)
// Mode.TARGET means pixels with color the same as removeColor are drawn on
p.setXfermode(new AvoidXfermode(removeColor, 0, AvoidXfermode.Mode.TARGET));

// draw transparent on the "brown" pixels
c.drawPaint(p);

// mb should now have transparent pixels where they were red before
3 голосов
/ 20 августа 2012

Решение user487252 работает как брелок до API уровня 16 (Jelly Bean), после которого AvoidXfermode, похоже, не работает вообще.

В моем конкретном случае использованияЯ преобразовал страницу PDF (через APV PDFView) в массив пикселей int[], который я собираюсь передать в Bitmap.createBitmap( int[], int, int, Bitmap.Config ).Эта страница содержит штриховые рисунки, нарисованные на белом фоне, и мне нужно удалить фон, сохранив сглаживание.

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

int [] pixels = ...;

for( int i = 0; i < pixels.length; i++ ) {
    // Invert the red channel as an alpha bitmask for the desired color.
    pixels[i] = ~( pixels[i] << 8 & 0xFF000000 ) & Color.BLACK;
}

Bitmap bitmap = Bitmap.createBitmap( pixels, width, height, Bitmap.Config.ARGB_8888 );

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

0 голосов
/ 22 июня 2011

Пиксель за пикселем - неплохой вариант. Только не вызывайте setPixel внутри вашего цикла. Заполните массив аргументов argb с помощью getPixels, измените его на месте, если вам не нужно сохранять оригинал, а затем вызовите setPixels в конце. Вы можете делать это построчно, если память вызывает беспокойство, или вы можете сделать все это за один раз. Вам не нужно заполнять целое растровое изображение для своего цвета наложения, поскольку вы просто выполняете простую замену (если текущий пиксель имеет цвет1, установите цвет2).

...