Aquí podría ser tu PUBLICIDAD


Cómo realizar un efecto compuesto MULTIPLY usando Graphics2D

votos
4

Tengo dos objetos diferentes javax.swing.Icon y quiero crear un nuevo icono que sea el compuesto de estos dos. Quiero que el compuesto sea un efecto MULTIPLY, similar a lo que obtendrías en cualquier aplicación de edición de imágenes similar a Photoshop cuando eliges esa opción. Específicamente, por cada píxel, si tiene el color Ca y Cb de la imagen 1 y la imagen respectivamente

Ca = (Ra, Ga, Ba) Cb = (Rb, Gb, Bb)

el quiero que la salida sea

Cc = (Ra Rb, Ga Gb, Ba * Bb)

Quiero hacer esto sobre la marcha (en tiempo real), así que tengo que hacer esto usando solo operaciones de Graphics2D. Miré AlphaComposite y no veo que esto se pueda hacer. ¿Alguien tiene alguna idea?

Publicado el 12/03/2009 a las 19:50
fuente por usuario Joel Carranza
En otros idiomas...        العربية       

2 respuestas

votos
3

Lo que necesitas es un compuesto alfa "multiplicado". Convenientemente, hice la misma pregunta hace un rato acerca de un efecto de "pantalla". Me señalaronhttp://www.curious-creature.org/2006/09/20/new-blendings-modes-for-java2d/ , que tiene el compuesto múltiple que necesita.

Respondida el 13/03/2009 a las 11:23
fuente por usuario Zarkonnen


Aquí podría ser tu PUBLICIDAD


votos
0

Dado que la mayoría de las respuestas a esta pregunta punta a una gran cantidad de recursos fuera del sitio pensé que iba a proporcionar una implementación completa aquí. Es esencialmente lo mismo que las grandes bibliotecas de los modos de fusión que puedes haber visto, pero he quitado la abstracción para los fines de la aplicación de solamente el modo de mezcla específica.

Algunas notas sobre el código de abajo:

  • Para utilizar simplemente g.setComposite(MultiplyComposite.Multiply)

  • La MultiplyCompositeclase implementa tanto Composite, y CompositeContextdado que para mis necesidades no hay nada diferente entre los dos. Si usted tiene un modo de fusión donde los parámetros pueden ser ajustados o la mezcla aplica de manera diferente que tendrá que poner en práctica las dos clases por separado.

  • Este código sólo funciona en buffers de 32 bits "entero". Usted tendría que modificar esto para trabajar con color de 16 bits (el cambio y cinta de 5/6 en lugar de bits de 8)

  • Este código funciona con el último byte como el canal alfa. Tendrá que modificar el código para trabajar con datos sin un canal alfa (24 bits).

  • El desplazamiento a la derecha por 8 en el mixPixelmétodo es una forma rápida de dividiendo por 256. por ejemplo. (a * b) >> 8en lugar de(a * b) / 256

  • Los píxeles se procesan una fila a la vez, de izquierda a derecha. Si usted tiene más memoria que podría modificar esto para procesar toda la memoria intermedia a la vez.


public class MultiplyComposite implements Composite, CompositeContext {
    protected void checkRaster(Raster r) {
        if (r.getSampleModel().getDataType() != DataBuffer.TYPE_INT) {
            throw new IllegalStateException("Expected integer sample type");
        }
    }

    @Override
    public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
        checkRaster(src);
        checkRaster(dstIn);
        checkRaster(dstOut);

        int width = Math.min(src.getWidth(), dstIn.getWidth());
        int height = Math.min(src.getHeight(), dstIn.getHeight());
        int x, y;
        int[] srcPixels = new int[width];
        int[] dstPixels = new int[width];

        for (y=0; y < height; y++) {
            src.getDataElements(0, y, width, 1, srcPixels);
            dstIn.getDataElements(0, y, width, 1, dstPixels);

            for (x=0; x < width; x++) {
                dstPixels[x] = mixPixel(srcPixels[x], dstPixels[x]);
            }

            dstOut.setDataElements(0, y, width, 1, dstPixels);
        }
    }

    private static int mixPixel(int x, int y) {
        int xb = (x) & 0xFF;
        int yb = (y) & 0xFF;
        int b = (xb * yb) / 255;

        int xg = (x >> 8) & 0xFF;
        int yg = (y >> 8) & 0xFF;
        int g = (xg * yg) / 255;

        int xr = (x >> 16) & 0xFF;
        int yr = (y >> 16) & 0xFF;
        int r = (xr * yr) / 255;

        int xa = (x >> 24) & 0xFF;
        int ya = (y >> 24) & 0xFF;
        int a = Math.min(255, xa + ya);

        return (b) | (g << 8) | (r << 16) | (a << 24);
    }


    @Override
    public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints) {
        return this;
    }

    @Override
    public void dispose() {

    }

    public static final MultiplyComposite Multiply = new MultiplyComposite();

}
Respondida el 06/11/2015 a las 07:28
fuente por usuario Kristopher Ives