Java DirectColorModel против IndexColorModel при работе с альфа - PullRequest
1 голос
/ 15 декабря 2009

У меня есть BufferedImage, который я получаю, у которого есть IndexColorModel. Затем я хочу применить AffineTransform с AffineTransformOP для создания преобразованной версии displayImage.

Вот фрагмент кода:

int type = isRGB() ? AffineTransformOp.TYPE_BILINEAR : AffineTransformOp.TYPE_NEAREST_NEIGHBOR;
AffineTransformOp op = new AffineTransformOp(atx, type);
displayImage = op.filter(displayImage, null);

Я запускаю это со многими изображениями, и из более раннего поста я обнаружил, что если я установил тип преобразования на билинейный, то у меня не хватило памяти, потому что я возвращал изображение с DirectColorModel. Однако эта DirectColorModel имела правильный альфа-канал (когда я нарисовал изображение на зеленом фоне после его перевода, я мог видеть зеленый цвет вокруг всего изображения). Когда я устанавливаю тип интерполяции для ближайшего соседа, пиксели над и слева от изображения становятся черными независимо от фона. Я предполагаю, что это означает, что альфа не устанавливается.

Может кто-нибудь сказать мне, как правильно установить альфа-канал с помощью IndexColorModel или изменить параметры AffineTransformOP таким образом, чтобы я получал IndexColorModel с правильной альфа-версией?

Спасибо !!

EDIT: Вот желаемый эффект, с AffineTransformOp.TYPE_BINLINEAR: alt text

Вот эффект, который я вижу с AffineTransformOp.TYPE_NEAREST_NEIGHBOR: alt text

Весь фон изначально закрашен зеленым для эффекта, и в обоих случаях изображение рисуется в позиции (0, 0).

1 Ответ

1 голос
/ 15 декабря 2009

Я не уверен, какого эффекта вы пытаетесь достичь, но я получаю ожидаемые результаты, когда настраиваю альфа до и / или после преобразования. Обычно я начинаю с setComposite(AlphaComposite.Clear), за которым следует fillRect(). Если все остальное терпит неудачу, вы можете filter() до WritableRaster, и грубым путем получить желаемый результат. Также вы можете посмотреть на RenderingHints, относящуюся к KEY_ALPHA_INTERPOLATION. Вот игрушка , которую я использую, чтобы экспериментировать с различными комбинациями альфа, режима и цвета.

Кажется, я помню, как видел эффект, который показывают ваши изображения. Вспоминая, что AffineTransformOp может возвращать изображение с разными координатами, особенно с вращением, я предполагаю, что добавленное «пустое» пространство не инициализируется правильно. Вы можете получить прозрачную рамку с кодом ниже, что также делает вращение вокруг центра несколько более симметричным:

private BufferedImage getSquareImage(BufferedImage image) {
    int w = image.getWidth();
    int h = image.getHeight();
    int max = Math.max(w, h);
    BufferedImage square = new BufferedImage(
            max, max, BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2d = square.createGraphics();
    g2d.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setComposite(AlphaComposite.Clear);
    g2d.fillRect(0, 0, max, max);
    g2d.setComposite(AlphaComposite.Src);
    g2d.drawImage(image, (max - w) / 2, (max - h) / 2, null);
    g2d.dispose();
    return square;
}
...