Frage

Gibt es eine Möglichkeit in J2ME, ein Bild (aus einer PNG -Datei mit Alpha geladen) in ein neues transparentes Graustufenbild zu konvertieren?

Bis jetzt habe ich nur die RGB -Werte bekommen, aber nicht das Alpha.

Vielen Dank.

Bearbeiten: Ja, es sollte 32 Bit Graustufen sein.

War es hilfreich?

Lösung

Ich habe die Lösung gefunden und hier ist der Code:

    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 gibt den Farbwert zurück, der auch den Alpha -Kanal enthält. Ich musste also nur jeden Wert im Array ändern und daraus ein Bild erstellen.

Ich habe im Nokia Forum ein hilfreiches Dokument gefunden: MidP 2.0: Arbeiten mit Pixel und DrawRGB ()

Andere Tipps

Vielen Dank für den Code zum Konvertieren in Greyscale. Ich bemerkte jedoch, dass dieser Code auf Nokia Series 40 -Geräten ziemlich langsam läuft.

Es gibt 2 Optimierungen. Das Hauptstark besteht darin, jede Objekterstellung in GetgraysCale () zu entfernen. Derzeit wird für jedes Pixel ein Array -Objekt erstellt. Für einen Durchschnitt, beispielsweise QVGA, Display, das 76800 Array -Objekte erstellt wird, das viel Müll ist und wahrscheinlich GC aufruft. Das Definieren des INT [4] als Feld in der Klasse entfernt diese Objekterstellung. Der Kompromiss hier ist eine kleine Menge zusätzlicher RAM, die für die Klasse verwendet werden.

Die zweite besteht darin, die Breite und Höhe in GetgraysCaleimage () zu zwischenstrahlen. Auf einigen Geräten wird die Methode auf GetWidth () und Geteight () ohne Optimierungen aufgerufen (ein JIT -Compiler ist in Ordnung, aber einige interpretierte Geräte nicht). Für QVGA werden die Getwidth () und Geteight () noch einmal zwischen ihnen als> 150000 bezeichnet.

Insgesamt fand ich diese modifizierte Version viel schneller :-)

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

(Wenn Sie wirklich keinen Klassendatenraum verwenden möchten, ersetzen Sie einfach die INT [] durch vier separate lokale INT -Variablen, die auf dem Stapel leben würden.)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top