Вопрос

Как мне изменить глобальное альфа-значение BufferedImage в Java?(То естьсделайте так, чтобы каждый пиксель изображения, имеющий альфа-значение 100, имел альфа-значение 80)

Это было полезно?

Решение

Я не верю, что существует хоть одна простая команда для этого.Несколько вариантов:

Первый - самый простой в реализации, IMO.

Другие советы

@Нил Коффи:Спасибо, я тоже искал это;однако ваш код работал у меня не очень хорошо (белый фон стал черным).

Я закодировал что-то вроде этого, и это работает отлично:

public void setAlpha(byte alpha) {       
    alpha %= 0xff; 
    for (int cx=0;cx<obj_img.getWidth();cx++) {          
        for (int cy=0;cy<obj_img.getHeight();cy++) {
            int color = obj_img.getRGB(cx, cy);

            int mc = (alpha << 24) | 0x00ffffff;
            int newcolor = color & mc;
            obj_img.setRGB(cx, cy, newcolor);            

        }

    }
}

Где obj_img - это буферизованное изображение.ТИП_INT_ARGB.

Я меняю альфа-код на setAlpha((байт)125);альфа-диапазон теперь равен 0-255.

Надеюсь, кто-нибудь найдет это полезным.

Это старый вопрос, поэтому я отвечаю не ради ОП, а для таких, как я, которые найдут этот вопрос позже.

Алфавитно - композитный

Как упоминалось в превосходном наброске @Michael's excellent, операция AlphaComposite может изменить альфа-канал.Но только определенными способами, которые мне несколько трудно понять:

enter image description here

является формула о том, как операция "over" влияет на альфа-канал.Более того, это влияет и на каналы RGB, поэтому, если у вас есть данные о цвете, которые должны быть неизменными, AlphaComposite - это не выход.

BufferedImageOps Буферизованное изображение

Посмотри - ка

Существует несколько разновидностей BufferedImageOp (см. 4.10.6 здесь).В более общем случае задача OP могла бы быть выполнена с помощью Посмотри - ка, что требует построения поисковых массивов.Чтобы изменить только альфа-канал, укажите идентификационный массив (массив, где table[i] = i) для каналов RGB и отдельный массив для альфа-канала.Заполните последний массив с помощью table[i] = f(i), где f() это функция, с помощью которой вы хотите преобразовать старое альфа-значение в новое.Например.если вы хотите "сделать так, чтобы каждый пиксель изображения, имеющий альфа-значение 100, имел альфа-значение 80", установите table[100] = 80.(Полный диапазон составляет от 0 до 255.) Смотрите как увеличить непрозрачность при размытии по Гауссу для примера кода.

Изменить масштаб

Но для подмножества этих случаев существует более простой способ сделать это, который не требует настройки таблицы подстановки.Если f() является простой линейной функцией, используйте Изменить масштаб.Например, если вы хотите установить newAlpha = oldAlpha - 20, используйте масштабирование с масштабным коэффициентом, равным 1, и смещением, равным -20.Если вы хотите установить newAlpha = oldAlpha * 0.8, используйте масштабный коэффициент, равный 0,8, и смещение, равное 0.В любом случае вам снова придется предоставить фиктивные масштабные коэффициенты и смещения для каналов RGB:

new RescaleOp({1.0f, 1.0f, 1.0f, /* alpha scaleFactor */ 0.8f},
              {0f, 0f, 0f, /* alpha offset */ -20f}, null)

Снова увидеть 4.10.6 здесь приведу несколько примеров, которые хорошо иллюстрируют принципы, но не являются специфичными для альфа-канала.

И то, и другое Изменить масштаб и Посмотри - ка разрешить изменять BufferedImage на месте.

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

public static void modAlpha(BufferedImage modMe, double modAmount) {
        //
    for (int x = 0; x < modMe.getWidth(); x++) {          
        for (int y = 0; y < modMe.getHeight(); y++) {
                //
            int argb = modMe.getRGB(x, y); //always returns TYPE_INT_ARGB
            int alpha = (argb >> 24) & 0xff;  //isolate alpha

            alpha *= modAmount; //similar distortion to tape saturation (has scrunching effect, eliminates clipping)
            alpha &= 0xff;      //keeps alpha in 0-255 range

            argb &= 0x00ffffff; //remove old alpha info
            argb |= (alpha << 24);  //add new alpha info
            modMe.setRGB(x, y, argb);            
        }
    }
}

Я на 99% уверен, что методы, которые утверждают, что имеют дело со значением "RGB", упакованным в int, на самом деле имеют дело с ARGB.Таким образом, вы должны быть в состоянии сделать что-то вроде:

for (all x,y values of image) {
  int argb = img.getRGB(x, y);
  int oldAlpha = (argb >>> 24);
  if (oldAlpha == 100) {
    argb = (80 << 24) | (argb & 0xffffff);
    img.setRGB(x, y, argb);
  }
}

Для повышения скорости, возможно, вы могли бы использовать методы для извлечения блоков значений пикселей.

Возможно, вам потребуется сначала скопировать ваш BufferedImage в изображение типа BufferedImage.TYPE_INT_ARGB.Если ваше изображение соответствует типу, скажите, BufferedImage.TYPE_INT_RGB, тогда альфа-компонент не будет установлен правильно.Если ваше BufferedImage имеет тип BufferedImage.TYPE_INT_ARGB, тогда приведенный ниже код работает. /** * Modifies each pixel of the BufferedImage so that the selected component (R, G, B, or A) * is adjusted by delta. Note: the BufferedImage must be of type BufferedImage.TYPE_INT_ARGB. * @param src BufferedImage of type BufferedImage.TYPE_INT_ARGB. * @param colorIndex 0=red, 1=green, 2=blue, 3= alpha * @param delta amount to change component * @return */ public static BufferedImage adjustAColor(BufferedImage src,int colorIndex, int delta) { int w = src.getWidth(); int h = src.getHeight(); assert(src.getType()==BufferedImage.TYPE_INT_ARGB); for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) { int rgb = src.getRGB(x,y); java.awt.Color color= new java.awt.Color(rgb,true); int red=color.getRed(); int green=color.getGreen(); int blue=color.getBlue(); int alpha=color.getAlpha(); switch (colorIndex) { case 0: red=adjustColor(red,delta); break; case 1: green=adjustColor(green,delta); break; case 2: blue=adjustColor(blue,delta); break; case 3: alpha=adjustColor(alpha,delta); break; default: throw new IllegalStateException(); } java.awt.Color adjustedColor=new java.awt.Color(red,green,blue,alpha); src.setRGB(x,y,adjustedColor.getRGB()); int gottenColorInt=src.getRGB(x,y); java.awt.Color gottenColor=new java.awt.Color(gottenColorInt,true); assert(gottenColor.getRed()== red); assert(gottenColor.getGreen()== green); assert(gottenColor.getBlue()== blue); assert(gottenColor.getAlpha()== alpha); } return src; } private static int adjustColor(int value255, int delta) { value255+= delta; if (value255<0) { value255=0; } else if (value255>255) { value255=255; } return value255; }

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top