0

Dans mon application Android, j'ai une voiture à partir de laquelle l'utilisateur peut cliquer et sélectionner différents panneaux. L'image est relativement compliquée (par opposition à celle collée ici) donc il est difficile de superposer les boutons dans les bons endroits. En outre, il y a beaucoup d'images différentes. La solution que je voudrais essayer:Android: créer dynamiquement un masque

  • détectez quel panneau a été sélectionné en utilisant un masque de couleur comme le suggère ici: https://blahti.wordpress.com/2012/06/26/images-with-clickable-areas/
  • En fonction des panneaux sélectionnés (dans mon exemple, le bleu et le vert) générer un masque .
    • Selon le masque, avoir une superposition rouge sur la voiture - juste un filtre de couleur ira bien.

(Première image représente les couleurs utilisées pour déterminer quel panneau a cliqué, la deuxième image représente le masque généré et la dernière image du « résultat »).

Le seul problème que j'ai est: Comment puis-je dynamiquement créer le masque? J'ai pensé à utiliser une méthode de type floodfill pour créer une nouvelle toile avec le 'mask' des panneaux sélectionnés. Mais, je m'inquiète que cela pourrait être trop lourd. Des suggestions plus simples? [my representation of the car images[1]

MISE À JOUR: Ok, donc je suis venu assez loin. Comme prévu, la création du masque est trop longue (2-4 secondes pour une petite image). Mais, alors j'ai découvert RenderScripts !! Je pense que je peux encore faire fonctionner ça. Le seul petit hic que j'ai maintenant est: Comment puis-je passer dans les couleurs qui ont été pressées?

Mon code actuel ressemble à ceci:

// create a bitmap for the mask. 
ImageView img = (ImageView) findViewById (mask); 
img.setDrawingCacheEnabled(true); 
Bitmap bitmap = Bitmap.createBitmap(img.getDrawingCache()); 

// Create a tiny bitmap to store the colours of the panels that are 
//'selected' 
Bitmap.Config conf = Bitmap.Config.ARGB_8888; // see other conf types 
Bitmap myBitmap = Bitmap.createBitmap(pickedPanels.size(), 1, conf); 
int [] myInts = new int[pickedPanels.size()]; 
for (int i = 0; i<pickedPanels.size(); i++){ 
    myInts[i] = pickedPanels.get(i).intValue(); 
} 
myBitmap.setPixels(myInts, 0, myBitmap.getWidth(), 0, 0, 
myBitmap.getWidth(),0); 

//Run thescript and set the output 
final RenderScript rs = RenderScript.create(this); 
final Allocation input = Allocation.createFromBitmap(rs, bitmap, 
Allocation.MipmapControl.MIPMAP_NONE,Allocation.USAGE_SCRIPT); 
final Allocation output = Allocation.createTyped(rs, input.getType()); 
     final ScriptC_singlesource script = new 
ScriptC_singlesource(rs); 
script.set_image(Allocation.createFromBitmap(rs, myBitmap, 
Allocation.MipmapControl.MIPMAP_NONE,Allocation.USAGE_SCRIPT)); 
script.set_imgWidth(pickedPanels.size()); 
script.forEach_root(input, output); 
output.copyTo(bitmap); 
img.setImageBitmap(bitmap); 

ImageView destim = (ImageView) findViewById (dest); 
destim.setDrawingCacheEnabled(true); 
destim.setImageBitmap(bitmap); 

et c'est le script:

#pragma version(1) 
#pragma rs java_package_name(za.co.overtake) 

rs_allocation image; 
int imgWidth; 

uchar4 RS_KERNEL root(uchar4 in, uint32_t x, uint32_t y) { 

for(int col = 0; col < imgWidth; col++){ 
    const uchar4 colour = *(const uchar4*)rsGetElementAt(image, col,0); 
    if (in.r == colour.r && in.g == colour.g && in.b == colour.b){ 
     in.r = 255; 
     in.g = 0; 
     in.b = 0; 
     break; 
    } else { 
     in.r = 0; 
     in.g = 255; 
     in.b = 0; 
     rsDebug("HELLLLLP>>", colour); 
    } 

} 
return in; 
} 

Mais, quand je tente de lire les valeurs de pixel de myBitmap (ou une image dans le script) , RGB est toujours 0.

(Désolé pour le mauvais nom, etc. Je suis devenu fou en essayant de comprendre cela)

Répondre

-1

Ok, j'ai compris. Dans mon code renderScript J'ai:

#pragma version(1) 
#pragma rs java_package_name(za.co.overtake) 

int*reds; 
int*greens;  
int*blues; 
int imgWidth; 

uchar4 RS_KERNEL root(uchar4 in, uint32_t x, uint32_t y) { 
    bool colourme = false; 
    for(int col = 0; col < imgWidth; col++){ 

     const int red = reds[col]; 
     const int green = greens[col]; 
     const int blue = blues[col]; 

     if (in.r == red && in.g == green && in.b == blue){ 
      colourme = true; 
     } 
    } 
    if (colourme) { 
     in.r = 255; 
     in.g = 0; 
     in.b = 0; 
     in.a = 50; 
    } else { 
     in.r = 0; 
     in.g = 0; 
     in.b = 0; 
     in.a = 0; 
    } 
    return in; 
} 

Puis en Java

public void showDamagedPanels(int dest, int mask) { 

    int noOfColours = pickedPanels.size(); 
    if (noOfColours > 0) { 
     ImageView img = (ImageView) findViewById (mask); 
     img.setDrawingCacheEnabled(true); 
     Bitmap bitmap = Bitmap.createBitmap(img.getDrawingCache()); 
     img.setDrawingCacheEnabled(false); 

     int [] reds = new int[noOfColours]; 
     int [] greens = new int[noOfColours]; 
     int [] blues = new int[noOfColours]; 

     for (int i = 0; i< noOfColours; i++){ 
      int colour = pickedPanels.get(i); 
      reds[i] = (colour >> 16) & 0xFF; 
      greens[i] = (colour >> 8) & 0xFF; 
      blues[i] = (colour >> 0) & 0xFF; 
     } 

     final RenderScript rs = RenderScript.create(this); 
     final Allocation input = Allocation.createFromBitmap(rs, bitmap, Allocation.MipmapControl.MIPMAP_NONE, 
       Allocation.USAGE_SCRIPT); 
     final Allocation output = Allocation.createTyped(rs, input.getType()); 
     final ScriptC_singlesource script = new ScriptC_singlesource(rs); 

     Allocation red = Allocation.createSized(rs, Element.I32(rs), reds.length); 
     red.copyFrom(reds); 
     script.bind_reds(red); 

     Allocation green = Allocation.createSized(rs, Element.I32(rs), greens.length); 
     green.copyFrom(greens); 
     script.bind_greens(green); 

     Allocation blue = Allocation.createSized(rs, Element.I32(rs), blues.length); 
     blue.copyFrom(blues); 
     script.bind_blues(blue); 

     script.set_imgWidth(pickedPanels.size()); 
     script.forEach_root(input, output); 
     output.copyTo(bitmap); 

     ImageView destim = (ImageView) findViewById (dest); 
     destim.setDrawingCacheEnabled(true); 
     destim.setImageBitmap(bitmap); 
    } else { 
     ImageView destim = (ImageView) findViewById (dest); 
     destim.setImageBitmap(null); 
    } 


} 

où dest est l'image de superposition et le masque dans l'image agissant comme masque. Donc, fondamentalement, quand un panneau est cliqué - placez sa couleur dans pickedPanels. Appelez ensuite la méthode showPanels, qui appelle le script. Le script vérifie les couleurs et définit l'image résultante en rouge ou en clair.

+0

La liaison est dépréciée. Utilisez les fonctions globales rs_allocation et rsGetElementAt_ *. – sakridge