Причина, по которой ваш код не работает должным образом, отчасти потому, что вы создаете новые BufferedImage
s на основе исходного типа:
BufferedImage(original.width, original.height, original.type)
Тип оригинала зависит от входного изображения . Для JPEG это обычно будет TYPE_3BYTE_BGR
(в котором нет альфы). Для PNG это зависит от типа или PNG (оттенки серого, палитра, истинный цвет, с альфа-каналом или без него и т. Д.). Ваш входной PNG, кажется, имеет истинный цвет с альфа, вероятно, в результате TYPE_4BYTE_ABGR
или TYPE_INT_ARGB
Вместо этого вы можете создать 4 изображения в градациях серого (только «уровни»), используя TYPE_BYTE_GRAY
, или, как вы делаете сейчас, 4 изображения ARGB, используя TYPE_INT_ARGB
(извините, если мой синтаксис Kotlin отключен, я в основном программирую на Java эти дней):
BufferedImage(original.width, original.height, BufferedImage.TYPE_INT_ARGB)
Далее, как уже указывал @AlexanderEgger, методы set/getRGB
работают в упакованном формате ARGB, поэтому вам нужно убедиться, что цвета непрозрачны (and
с , просто цветовой маской, приведет к полностью прозрачному цвету):
val a = color and 0xff000000.toInt()
val r = (color and 0x00ff0000) or 0xff000000.toInt()
val g = (color and 0x0000ff00) or 0xff000000.toInt()
val b = (color and 0x000000ff) or 0xff000000.toInt()
Или, если вам нравится подход с уровнями, вы делаете то, что предлагает @MarkSetchell, и создаете все серые изображения (опять же, синтаксис Kotlin может быть немного неправильным):
BufferedImage(original.width, original.height, BufferedImage.TYPE_BYTE_GRAY)
...
val a = (color >> 24) and 0xff
val r = (color >> 16) and 0xff
val g = (color >> 8) and 0xff
val b = color and 0xff
val aa = 0xff000000.toInt() or (a << 16) or (a << 8) or a
val rr = 0xff000000.toInt() or (r << 16) or (r << 8) or r
val gg = 0xff000000.toInt() or (g << 16) or (g << 8) or g
val bb = 0xff000000.toInt() or (b << 16) or (b << 8) or b
(и передать aa
, rr
, gg
и bb
до setRGB
).