سؤال

هل هناك أي إمكانية في J2ME لتحويل صورة (محملة من ملف PNG باستخدام ألفا) صورة رمادية شفافة جديدة؟

حتى الآن فقط حصلت فقط على قيم RGB، ولكن ليس ألفا.

شكرا.

تحرير: نعم، يجب أن يكون 32 بت رمادي.

هل كانت مفيدة؟

المحلول

لقد وجدت الحل وهنا رمز:

    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 قيمة اللون التي تتضمن أيضا قناة ألفا. لذلك اضطررت فقط لتغيير كل قيمة في الصفيف وإنشاء صورة من ذلك.

لقد وجدت وثيقة مفيدة في منتدى نوكيا: MIDP 2.0: العمل مع وحدات البكسل والاسترجل ()

نصائح أخرى

شكرا لك على التحويل إلى Greyscale. ومع ذلك، لاحظت أنه على أجهزة Nokia Series 40، يعمل هذا الرمز ببطء شديد.

هناك 2 تحسينات. واحد الرئيسي هو إزالة أي إنشاء كائن في GetGrayScale (). حاليا، يتم إنشاء كائن صفيف لكل بكسل. بالنسبة لمتوسط، قل QVGA، عرض أن هي 76800 كائنات صفيف تم إنشاؤها، وهو الكثير من القمامة، وربما يحصل على GC. تحديد INT [4] كحقل في الفصل يزيل إنشاء الكائن هذا. التجانس هنا هو كمية صغيرة من ذاكرة الوصول العشوائي الإضافية المستخدمة للفئة.

والثاني هو التخزين المؤقت العرض والارتفاع في GetGrayScaleImage (). على بعض الأجهزة، سيتم استدعاء الأسلوب المكالمات إلى GetWidth () و GetHeight () بشكل متكرر دون تحسينات (سيكون مترجم JIT على ما يرام ولكن بعض الأجهزة المفسرة لا). لذلك، مرة أخرى بالنسبة ل QVGA، سيتم استدعاء GetWidth () و GetHeight () بعض> 150000 بينهما.

في الكل، وجدت هذه النسخة المعدلة ركض أسرع بكثير :-)

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

(إذا كنت لا ترغب حقا في استخدام مساحة البيانات الفئة، فما عليك سوى استبدال INT [] بأربعة متغيرات ملكية محلية منفصلة ستعيش على المكدس)

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top