J2ME: преобразовать прозрачное изображение PNG в серогойс

StackOverflow https://stackoverflow.com/questions/2412054

Вопрос

Есть ли возможность в 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 возвращает значение цвета, которое также включает в себя альфа -канал. Поэтому мне нужно было изменить каждое значение в массиве и создать из этого изображение.

Я нашел полезный документ на форуме Nokia: MIDP 2.0: Работа с Pixels и DrawRgb ()

Другие советы

Спасибо за код по преобразованию в 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 [] на четырех отдельных локальных переменных Int, которые будут жить в стеке)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top