Pregunta

¿Hay alguna posibilidad en J2ME para convertir una imagen (cargada de un archivo PNG con alfa) a una nueva imagen transparente de escala de grises?

Hasta ahora solo obtenía los valores RGB, pero no el alfa.

Gracias.

EDITAR: Sí, debería ser una escala de grises de 32 bits.

¿Fue útil?

Solución

Encontré la solución y aquí está el código:

    public Image getGrayScaleImage() {
    int[] rgbData = new int[getWidth() * getHeight()];
    image.getRGB(rgbData, 0, getWidth(), 0, 0, getWidth(), getHeight());
    for (int x = 0; x < getWidth() * getHeight(); x++) {
        rgbData[x] = getGrayScale(rgbData[x]);
    }
    Image grayImage = Image.createRGBImage(rgbData, getWidth(), getHeight(), true);
    return grayImage;
}

private int getGrayScale(int c) {
    int[] p = new int[4];
    p[0] = (int) ((c & 0xFF000000) >>> 24); // Opacity level
    p[1] = (int) ((c & 0x00FF0000) >>> 16); // Red level
    p[2] = (int) ((c & 0x0000FF00) >>> 8); // Green level
    p[3] = (int) (c & 0x000000FF); // Blue level

    int nc = p[1] / 3 + p[2] / 3 + p[3] / 3;
    // a little bit brighter
    nc = nc / 2 + 127;

    p[1] = nc;
    p[2] = nc;
    p[3] = nc;

    int gc = (p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]);
    return gc;
}

GetRGB devuelve el valor de color que también incluye el canal alfa. Así que solo tuve que cambiar cada valor en la matriz y crear una imagen a partir de eso.

Encontré un documento útil en el foro de Nokia: MIDP 2.0: Trabajando con píxeles y dibujo ()

Otros consejos

Gracias por el código de convertir a Greyscale. Sin embargo, noté que, en los dispositivos Nokia Series 40, este código se ejecuta bastante lentamente.

Hay 2 optimizaciones. El principal es eliminar cualquier creación de objetos en getgrayscale (). Actualmente, se crea un objeto de matriz para cada píxel. Para un promedio, digamos QVGA, muestra que se crean objetos de matriz 76800, que es mucha basura, y probablemente invocará GC. Definir el int [4] como un campo en la clase elimina esta creación de objetos. La compensación aquí es una pequeña cantidad de RAM adicional utilizada para la clase.

El segundo es almacenar en caché el ancho y la altura en getgrayscaleImage (). En algunos dispositivos, el método llama a getWidth () y getheight () se llamará repetidamente sin optimizaciones (un compilador JIT estará bien pero algunos dispositivos interpretados no). Entonces, nuevamente para QVGA, el GetWidth () y Getheight () se llamarán algunos> 150000 entre ellos.

En total, encontré que esta versión modificada se ejecutó mucho más rápido :-)

public Image getGrayScaleImage(Image screenshot) {
    int width = getWidth();
    int height = getHeight();
    int screenSizeInPixels = (width * height);

    int[] rgbData = new int[width * height];

    image.getRGB(rgbData, 0, width, 0, 0, width, height);
    for (int x = 0; x < screenSizeInPixels ; x++) {
        rgbData[x] = getGrayScale(rgbData[x]);
    }

    Image grayImage = Image.createRGBImage(rgbData, width, height, true);
    return grayImage;
}

static int[] p = new int[4];
private int getGrayScale(int c) {

    p[0] = (int) ((c & 0xFF000000) >>> 24); // Opacity level
    p[1] = (int) ((c & 0x00FF0000) >>> 16); // Red level
    p[2] = (int) ((c & 0x0000FF00) >>> 8); // Green level
    p[3] = (int) (c & 0x000000FF); // Blue level

    int nc = p[1] / 3 + p[2] / 3 + p[3] / 3;
    // a little bit brighter
    nc = nc / 2 + 127;

    p[1] = nc;
    p[2] = nc;
    p[3] = nc;

    int gc = (p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]);
    return gc;
}

(Si realmente no desea usar el espacio de datos de clase, simplemente reemplace el int [] con cuatro variables INT locales separadas que vivirían en la pila)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top