2013-03-16 4 views
2

J'ai le problème suivant. J'ai commencé avec une routine de transformation bitmap qui fonctionne parfaitement pour tout type de transformation que je peux y lancer.Transformation de bitmap en mémoire

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

Mais il est lent Douloureusement - causée par les frères, sœurs getPixel()/setPixel(). Pas de problème, dis-je, je vais juste utiliser un tampon mémoire (comme dans les anciens jours StretchBlt()). Alors, je l'ai fait une Réécriture majeure, la création de la pierre précieuse suivante du génie logiciel :)

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

court vite, même obtient un résultat correct S'IL Y A PAS DE TRANSFORMATION. Mais il s'effondre si j'essaie de masser les pixels (appliquer des transformations). J'ai donc comparé les pixels ARGB de getPixel() et les valeurs des pixels de getPixels (...) et ils sont différents (bon, les 2 premiers sont les mêmes, ce qui me laisse avec environ zillion qui ne le sont pas).

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 
.... 

Quelqu'un sait ce que je fais mal cette fois? Je ne suis pas prêt à abandonner la vitesse de la solution mem-array pour le moment. Merci, sean

Répondre

1

Il devrait être

int off = (y * wid) + x; 

D'ailleurs, je pense que les deux boucles est inutile, vous pouvez simplement faire:

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

Merci un bouquet. Ça ne m'étonne jamais de me rendre stupide après 20 heures de codage et 10 cafés pour me tenir éveillé. Et je n'hésite jamais à montrer le monde. Quoi qu'il en soit, réduire le code à une boucle, accéléré les choses encore plus loin. Cela fonctionne vraiment bien. sean – seanpj

+0

De rien Sean. Profitez du codage :) –

Questions connexes