Преобразование растрового изображения в оттенки серого в BlackBerry J2Me

Я пытался использовать образцы отсюда:
J2ME: преобразовать прозрачный Изображение PNG в оттенках серого
и здесь:
http://www.java2s.com/Code/Java/Collections-Data-Structure/intarraytobytearray.htm

для преобразования объекта растрового изображения в оттенки серого на лету, но у меня возникают проблемы, когда я пытаюсь перекодировать свой байт в изображение, и я получаю следующую ошибку/стек:

(Suspended (exception IllegalArgumentException))    
EncodedImage.createEncodedImage(byte[], int, int, String) line: 367 
EncodedImage.createEncodedImage(byte[], int, int) line: 279 
ScreenTemp.getGrayScaleImage(Bitmap) line: 404

Вот мой код, который я пытаюсь:

    Bitmap btemp = getGrayScaleImage(Bitmap.getBitmapResource("add.png"));
    BitmapField bftemp = new BitmapField(btemp, BitmapField.FOCUSABLE | BitmapField.FIELD_HCENTER | BitmapField.FIELD_VCENTER);
    add(bftemp);


    public Bitmap getGrayScaleImage(Bitmap image) {
    int width = image.getWidth();
    int height = image.getHeight();     
    int[] rgbData = new int[width * height];        
    image.getARGB(rgbData, 0, width, 0, 0, width, height);
    for (int x = 0; x < width*height ; x++) {
        rgbData[x] = getGrayScale(rgbData[x]);
    }
    byte[] b = int2byte(rgbData);
    final EncodedImage jpegPic = EncodedImage.createEncodedImage(b, 0, b.length);
    return jpegPic.getBitmap();
}
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;
}
private static byte[] int2byte(int[] src) {
    int srcLength = src.length;
    byte[]dst = new byte[srcLength << 2];

    for (int i=0; i<srcLength; i++) {
        int x = src[i];
        int j = i << 2;
        dst[j++] = (byte) ((x >>> 0) & 0xff);           
        dst[j++] = (byte) ((x >>> 8) & 0xff);
        dst[j++] = (byte) ((x >>> 16) & 0xff);
        dst[j++] = (byte) ((x >>> 24) & 0xff);
    }
    return dst;
}

Любая помощь будет здорово!

Спасибо, Джастин

РЕДАКТИРОВАТЬ: благодаря приведенной ниже информации я смог решить эту проблему. Вот код. Вам больше не нужен int2byte, и вот обновленный метод getGrayScaleImage:

public Bitmap getGrayScaleImage(Bitmap image) {
    int width = image.getWidth();
    int height = image.getHeight();     
    int[] rgbData = new int[width * height];        
    image.getARGB(rgbData, 0, width, 0, 0, width, height);
    for (int x = 0; x < width*height ; x++) {
        rgbData[x] = getGrayScale(rgbData[x]);
    }
    byte[] b = int2byte(rgbData);
    Bitmap bit = new Bitmap(width, height);
    bit.setARGB(rgbData, 0, width, 0, 0, width, height);
    return bit;
}

person Justin    schedule 10.08.2011    source источник


Ответы (2)


Цитата из Javadoc EncodedImage:

Если формат изображения не распознан, выдается IllegalArgumentException.

Почему вы возитесь с EncodedImage? Похоже, вы должны иметь возможность просто создать второй Bitmap и использовать setARGB().

person Scott W    schedule 10.08.2011

Чтобы расширить Scott W ответ.

EncodedImage.createEncodedImage(byte[] data, int offset, int length) ожидает массив байтов поддерживаемого типа изображения (TIFF, BMP, JPEG, GIF, WBMP или PNG). Например, если вы открыли файл изображения JPEG, прочитали байты файла, то можно было бы использовать полученные байты для создания EncodedImage (на самом деле это будет JPEGEncodedImage).

Итак, как говорит Scott W, вы должны использовать Bitmap.setARGB() для результирующего массива байтов, чтобы иметь Bitmap с преобразованными данными.

И затем, если вам нужно сохранить изображение в виде файла JPEG, вы можете использовать что-то вроде этого:

JPEGEncodedImage eImage = JPEGEncodedImage.encode(bitmap, 75);
byte[] fileData = eImage.getData();
// open a FileConnection and write the fileData
person Vit Khudenko    schedule 11.08.2011
comment
Спасибо за продолжение, Скотт и Архимед, но тип данных — это формат файла png, и я просто пытался преобразовать каждый пиксель в оттенки серого. Я попробую то, что вы предложили, чтобы увидеть, если мне повезет. Спасибо за быстрые ответы! - person Justin; 11.08.2011