Преобразувайте растерно изображение в нива на сивото в 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)


Цитирайки от EncodedImage Javadoc:

Ако форматът на изображението не бъде разпознат, се хвърля IllegalArgumentException.

Защо се занимавате с EncodedImage? Изглежда, че трябва да можете просто да създадете второ растерно изображение и да използвате 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 файл, можете да използвате smth като това:

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