2013-03-16 2 views
2

У меня есть следующая проблема. Я начал с подпрограммы растрового преобразования, которая работает безупречно для любых преобразований, которые я могу бросить на нее.Преобразование растрового изображения в памяти

Bitmap transform(Bitmap src) { 
    // ... any kind of transformation , for example GAMMA 
    double gama = 0.8; 
    int[] tR = new int[256]; 
    int[] gG = new int[256]; 
    int[] tB = new int[256]; 
    for(int i = 0; i < 256; ++i) { 
     tR[i] = (int)Math.min(255, (int)((255.0 * Math.pow(i/255.0, 1.0/gama)) + 0.5)); 
     tG[i] = (int)Math.min(255, (int)((255.0 * Math.pow(i/255.0, 1.0/gama)) + 0.5)); 
     tB[i] = (int)Math.min(255, (int)((255.0 * Math.pow(i/255.0, 1.0/gama)) + 0.5)); 
    } 
    // apply transformation to the old bitmap -> bmOut 
    int wid = src.getWidth(), hei = src.getHeight(); 
    Bitmap bmOut = Bitmap.createBitmap(wid, hei, src.getConfig()); 
    int A, R, G, B; 
    for(int x = 0; x < wid; x++) { 
     for(int y = 0; y < hei; y++) { 
     int pixel = src.getPixel(x, y); 
     A = Color.alpha(pixel); 
     R = tR[Color.red(pixel)]; 
     G = tG[Color.green(pixel)]; 
     B = tB[Color.blue(pixel)]; 
     bmOut.setPixel(x, y, Color.argb(A, R, G, B)); 
     } 
    } 
    return bmOut; 
    } 

Но это крайне медленно - в результате GetPixel()/SetPixel братья (сестры),. Нет проблем, говорит я, я просто использую буфер памяти (например, в старые дни StretchBlt()). Таким образом, я сделал КАПИТАЛЬНЫЙ переписывают, создавая следующий камень программной инженерии :)

Bitmap transform(Bitmap src) { 
    // ... transformation array are built here 

    // apply transformation 
    int wid = src.getWidth(), hei = src.getHeight(); 
    Bitmap bmOut = Bitmap.createBitmap(wid, hei, src.getConfig()); 

    int[] pixs = new int[wid*hei];     // changed 
    src.getPixels(pixs, 0, wid, 0, 0, wid, hei); // changed 

    int A, R, G, B; 
    for(int x = 0; x < wid; x++) { 
     for(int y = 0; y < hei; y++) { 
     int off = (x * y) + y;     // changed 
     int pixel = pixs[off];      // changed 
     A = Color.alpha(pixel); 
     R = tR[Color.red(pixel)]; 
     G = tG[Color.green(pixel)]; 
     B = tB[Color.blue(pixel)]; 
     pixs[off] = Color.argb(A, R, G, B);   // changed  
     } 
    } 
    bmOut.setPixels(pixs, 0, wid, 0, 0, wid, hei); // changed 
    return bmOut; 
    } 

работает быстро, даже получает правильный результат ЕСЛИ НЕТ ПРЕОБРАЗОВАНИЯ. Но он разваливается , если я пытаюсь массировать пиксели (применять преобразования). Таким образом, я сопоставлял ARGB-пиксели от getPixel() и массива значений пикселей от getPixels (...), и они разные (ну, первые 2 одинаковы, что оставляет меня примерно с zillion, которых нет).

array  getPixel 
a r g b a r g b 
------------------ 
ff65340b ff65340b 
ff64330a ff64330a 
ff66320b ff63320a 
ff65310a ff613008 
ff66300c ff62300d 
ff67310d ff62300d 
ff68300d ff622d0d 
ff69310e ff5f2a0a 
.... 

Кто-нибудь знает, что я делаю неправильно на этот раз? Я не хочу отказаться от скорости решения . Спасибо, Sean

ответ

1

Это должно быть

int off = (y * wid) + x; 

Кстати, я думаю, что две петли не нужно, вы можете просто сделать:

for (int off = pixs.length - 1; off >= 0; off--) 
+0

Благодаря кучу. Он никогда не захватывает, чтобы удивить меня, как глупо я могу получить после 20 часов кодирования и 10 кофе, чтобы я не спал. И я никогда не стесняюсь показывать мир. Во всяком случае, сокращение кода до одного цикла, ускорило ситуацию еще больше. Он работает очень хорошо. sean – seanpj

+0

Добро пожаловать, Шон. Наслаждайтесь кодированием :) –

Смежные вопросы