Domanda

c'è qualche possiblity in J2ME per convertire un'immagine (caricata da un file png con alpha) per una nuova scala di grigio trasparente?

Fino ad ora ho ottenuto solo i valori RGB, ma non l'alfa.

Grazie.

Modifica: sì, dovrebbe essere a 32 bit in scala di grigi

.
È stato utile?

Soluzione

Ho trovato la soluzione ed ecco il codice:

    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 restituisce il valore del colore che comprende anche il canale alfa. Così ho dovuto solo cambiare ogni valore nella matrice e creare un'immagine da questo.

Ho trovato un documento utile nel forum nokia: MIDP 2.0: Lavorare con Pixel e drawRGB ()

Altri suggerimenti

Grazie per il codice sulla conversione in scala di grigi. Tuttavia, ho notato che, sul Nokia Serie 40, questo codice viene eseguito piuttosto lentamente.

Ci sono 2 ottimizzazioni. Il principale è quello di rimuovere ogni creazione oggetto in getGrayScale (). Attualmente, un oggetto array viene creata per ogni pixel. Per una media, dire QVGA, schermo che è 76800 oggetti array creati, che è un sacco di immondizia, e probabilmente richiamare GC. Definizione del int [4] come un campo nella classe rimuove questo la creazione di oggetti. Il trade-off: ecco un piccola quantità di RAM aggiuntivo utilizzato per la classe.

Il secondo è quello di memorizzare nella cache la larghezza e l'altezza in getGrayScaleImage (). In alcuni dispositivi, il metodo chiama a getWidth () e getHeight () sarà chiamato ripetutamente senza ottimizzazioni (un compilatore JIT sarà OK ma comunque interpretato dispositivi non). Così, ancora una volta per QVGA, la getWidth () e getHeight () sarà chiamato alcuni> 150000 tra di loro.

In tutto, ho trovato questa versione modificata di corsa molto più veloce: -)

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;
}

(Se davvero non si vuole utilizzare lo spazio dei dati di classe, basta sostituire l'int [] con quattro variabili int locali separati che vivono sullo stack)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top