2013-01-28 21 views
10

Voglio sfocare e sbloccare le immagini a livello di codice in Android.Android sfocatura a livello di codice disegnabile in anteprima

Ho sentito che la "sfocatura" della bandiera Android non è più supportata dopo l'API 14, ma volevo comunque utilizzare i metodi Java. Il mio problema principale è la manipolazione della bitmap da un drawable di Imageview.

Come si ottiene la bitmap da una vista di immagini e la si può manipolare (probabilmente si utilizzerà la sfocatura gaussiana) e si può tornare alla visualizzazione di immagini? Penso che il processo implichi l'estrazione del drawable, la conversione del drawable in un bitmap, il mio metodo blur su quella bitmap e quindi il reverse fino a quando non viene impostato nuovamente sull'immagineview

ma vorrei che il processo fosse esplicitato, grazie you

+1

hai guardato http://stackoverflow.com/a/2068981/1204134? So che non è una sfocatura gaussiana, ma potrebbe funzionare. –

+0

Non so se esiste un modo semplice per eseguire una sfocatura gaussiana su bitmap. Ma se hai a che fare con un'applicazione che farà un sacco di elaborazione delle immagini, ti suggerisco di utilizzare OpenCV per Android. –

+0

Ho usato la risposta di @AlexJuanGittemeier, è molto veloce, ~ 250 ms in un viewpager .. sto ancora testando l'utilizzo della memoria – CQM

risposta

14

Di seguito sono riportati i codici per l'implementazione della sfocatura gaussiana. Possa questo può aiutare a

import android.graphics.Bitmap; 
import android.graphics.Matrix; 

/** 
* @author robert.hinds 
* 
* Wrapper class for the Android Bitmap - used by all filters 
* 
*/ 
public class AndroidImage { 

    //original bitmap image 
    private Bitmap image; 

    //format of image (jpg/png) 
    private String formatName; 

    //dimensions of image 
    private int width, height; 

    // RGB Array Color 
    protected int[] colourArray; 

    public AndroidImage(Bitmap img){   
     this.image = img; 
     formatName = "jpg"; 
     width = img.getWidth(); 
     height = img.getHeight(); 
     updateColourArray(); 
    } 


    /** 
    * Method to reset the image to a solid colour 
    * 
    * @param color - colour to rest the entire image to 
    */ 
    public void clearImage(int color){ 
     for(int y=0; y<height; y++){ 
      for(int x=0; x<width; x++){ 
       image.setPixel(x, y, color); 
      } 
     } 
    } 


    /** 
    * Set colour array for image - called on initialisation 
    * by constructor 
    * 
    * @param bitmap 
    */ 
    private void updateColourArray(){ 
     colourArray = new int[width * height]; 
     image.getPixels(colourArray, 0, width, 0, 0, width, height); 
     int r, g, b; 
     for (int y = 0; y < height; y++){ 
      for (int x = 0; x < width; x++){ 
       int index = y * width + x; 
       r = (colourArray[index] >> 16) & 0xff; 
       g = (colourArray[index] >> 8) & 0xff; 
       b = colourArray[index] & 0xff; 
       colourArray[index] = 0xff000000 | (r << 16) | (g << 8) | b; 
      } 
     } 
    } 


    /** 
    * Method to set the colour of a specific pixel 
    * 
    * @param x 
    * @param y 
    * @param colour 
    */ 
    public void setPixelColour(int x, int y, int colour){ 
     colourArray[((y*image.getWidth()+x))] = colour; 
     image.setPixel(x, y, colour); 
    } 

    /** 
    * Get the colour for a specified pixel 
    * 
    * @param x 
    * @param y 
    * @return colour 
    */ 
    public int getPixelColour(int x, int y){ 
     return colourArray[y*width+x]; 
    } 

    /** 
    * Set the colour of a specified pixel from an RGB combo 
    * 
    * @param x 
    * @param y 
    * @param c0 
    * @param c1 
    * @param c2 
    */ 
    public void setPixelColour(int x, int y, int c0, int c1, int c2){ 
     colourArray[((y*image.getWidth()+x))] = (255 << 24) + (c0 << 16) + (c1 << 8) + c2; 
     image.setPixel(x, y, colourArray[((y*image.getWidth()+x))]); 
    } 

    /** 
    * Method to get the RED colour for the specified 
    * pixel 
    * @param x 
    * @param y 
    * @return colour of R 
    */ 
    public int getRComponent(int x, int y){ 
     return (getColourArray()[((y*width+x))]& 0x00FF0000) >>> 16; 
    } 


    /** 
    * Method to get the GREEN colour for the specified 
    * pixel 
    * @param x 
    * @param y 
    * @return colour of G 
    */ 
    public int getGComponent(int x, int y){ 
     return (getColourArray()[((y*width+x))]& 0x0000FF00) >>> 8; 
    } 


    /** 
    * Method to get the BLUE colour for the specified 
    * pixel 
    * @param x 
    * @param y 
    * @return colour of B 
    */ 
    public int getBComponent(int x, int y){ 
     return (getColourArray()[((y*width+x))] & 0x000000FF); 
    } 



    /** 
    * Method to rotate an image by the specified number of degrees 
    * 
    * @param rotateDegrees 
    */ 
    public void rotate (int rotateDegrees){ 
     Matrix mtx = new Matrix(); 
     mtx.postRotate(rotateDegrees); 
     image = Bitmap.createBitmap(image, 0, 0, width, height, mtx, true); 
     width = image.getWidth(); 
     height = image.getHeight(); 
     updateColourArray(); 
    } 


    /** 
    * @return the image 
    */ 
    public Bitmap getImage() { 
     return image; 
    } 


    /** 
    * @param image the image to set 
    */ 
    public void setImage(Bitmap image) { 
     this.image = image; 
    } 


    /** 
    * @return the formatName 
    */ 
    public String getFormatName() { 
     return formatName; 
    } 


    /** 
    * @param formatName the formatName to set 
    */ 
    public void setFormatName(String formatName) { 
     this.formatName = formatName; 
    } 


    /** 
    * @return the width 
    */ 
    public int getWidth() { 
     return width; 
    } 


    /** 
    * @param width the width to set 
    */ 
    public void setWidth(int width) { 
     this.width = width; 
    } 


    /** 
    * @return the height 
    */ 
    public int getHeight() { 
     return height; 
    } 


    /** 
    * @param height the height to set 
    */ 
    public void setHeight(int height) { 
     this.height = height; 
    } 


    /** 
    * @return the colourArray 
    */ 
    public int[] getColourArray() { 
     return colourArray; 
    } 


    /** 
    * @param colourArray the colourArray to set 
    */ 
    public void setColourArray(int[] colourArray) { 
     this.colourArray = colourArray; 
    } 

} 

import com.bvise.fotoflipper.core.AndroidImage; 




public interface IAndroidFilter { 

    public AndroidImage process(AndroidImage imageIn); 
} 


import android.graphics.Bitmap; 
import android.graphics.Color; 

public class ConvolutionMatrix 
{ 
    public static final int SIZE = 3; 

    public double[][] Matrix; 
    public double Factor = 1; 
    public double Offset = 1; 

    public ConvolutionMatrix(int size) { 
     Matrix = new double[size][size]; 
    } 

    public void setAll(double value) { 
     for (int x = 0; x < SIZE; ++x) { 
      for (int y = 0; y < SIZE; ++y) { 
       Matrix[x][y] = value; 
      } 
     } 
    } 

    public void applyConfig(double[][] config) { 
     for(int x = 0; x < SIZE; ++x) { 
      for(int y = 0; y < SIZE; ++y) { 
       Matrix[x][y] = config[x][y]; 
      } 
     } 
    } 

    public static Bitmap computeConvolution3x3(Bitmap src, ConvolutionMatrix matrix) { 
     int width = src.getWidth(); 
     int height = src.getHeight(); 
     Bitmap result = Bitmap.createBitmap(width, height, src.getConfig()); 

     int A, R, G, B; 
     int sumR, sumG, sumB; 
     int[][] pixels = new int[SIZE][SIZE]; 

     for(int y = 0; y < height - 2; ++y) { 
      for(int x = 0; x < width - 2; ++x) { 

       // get pixel matrix 
       for(int i = 0; i < SIZE; ++i) { 
        for(int j = 0; j < SIZE; ++j) { 
         pixels[i][j] = src.getPixel(x + i, y + j); 
        } 
       } 

       // get alpha of center pixel 
       A = Color.alpha(pixels[1][1]); 

       // init color sum 
       sumR = sumG = sumB = 0; 

       // get sum of RGB on matrix 
       for(int i = 0; i < SIZE; ++i) { 
        for(int j = 0; j < SIZE; ++j) { 
         sumR += (Color.red(pixels[i][j]) * matrix.Matrix[i][j]); 
         sumG += (Color.green(pixels[i][j]) * matrix.Matrix[i][j]); 
         sumB += (Color.blue(pixels[i][j]) * matrix.Matrix[i][j]); 
        } 
       } 

       // get final Red 
       R = (int)(sumR/matrix.Factor + matrix.Offset); 
       if(R < 0) { R = 0; } 
       else if(R > 255) { R = 255; } 

       // get final Green 
       G = (int)(sumG/matrix.Factor + matrix.Offset); 
       if(G < 0) { G = 0; } 
       else if(G > 255) { G = 255; } 

       // get final Blue 
       B = (int)(sumB/matrix.Factor + matrix.Offset); 
       if(B < 0) { B = 0; } 
       else if(B > 255) { B = 255; } 

       // apply new pixel 
       result.setPixel(x + 1, y + 1, Color.argb(A, R, G, B)); 
      } 
     } 

     // final image 
     return result; 
    } 
} 

import android.graphics.Bitmap; 

import com.bvise.fotoflipper.core.AndroidImage; 
import com.bvise.fotoflipper.core.ConvolutionMatrix; 
import com.bvise.fotoflipper.filters.IAndroidFilter; 

public class GaussianBlur implements IAndroidFilter{ 

    @Override 
    public AndroidImage process(AndroidImage imageIn) { 
     // TODO Auto-generated method stub 
     Bitmap src=imageIn.getImage(); 
     double[][] GaussianBlurConfig = new double[][] { 
       { 1, 2, 1 }, 
       { 2, 4, 2 }, 
       { 1, 2, 1 } 
      }; 
      ConvolutionMatrix convMatrix = new ConvolutionMatrix(3); 
      convMatrix.applyConfig(GaussianBlurConfig); 
      convMatrix.Factor = 200; 
      convMatrix.Offset = 0; 
      return new AndroidImage(ConvolutionMatrix.computeConvolution3x3(src, convMatrix)); 
    } 


} 
+0

cool, quanto è veloce e come gestisce la memoria? Stavo pensando di usare il codice JNI da un altro suggerimento – CQM

+0

questo processo molto veloce e gestisce efficacemente la memoria –

4

Per offuscamento un IMAGEVIEW o bitmap, renderScript viene utilizzato in combinazione con la libreria Picasso.

public class Blur implements Transformation { 
    protected static final int UP_LIMIT = 25; 
    protected static final int LOW_LIMIT = 1; 
    protected final Context context; 
    protected final int blurRadius; 


    public Blur(Context context, int radius) { 
     this.context = context; 

     if(radius<LOW_LIMIT){ 
      this.blurRadius = LOW_LIMIT; 
     }else if(radius>UP_LIMIT){ 
      this.blurRadius = UP_LIMIT; 
     }else 
      this.blurRadius = radius; 
    } 

    @Override 
    public Bitmap transform(Bitmap source) { 
     Bitmap sourceBitmap = source; 

     Bitmap blurredBitmap; 
     blurredBitmap = Bitmap.createBitmap(sourceBitmap); 

     RenderScript renderScript = RenderScript.create(context); 

     Allocation input = Allocation.createFromBitmap(renderScript, 
       sourceBitmap, 
       Allocation.MipmapControl.MIPMAP_FULL, 
       Allocation.USAGE_SCRIPT); 



     Allocation output = Allocation.createTyped(renderScript, input.getType()); 

     ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(renderScript, 
            Element.U8_4(renderScript)); 

     script.setInput(input); 
     script.setRadius(blurRadius); 

     script.forEach(output); 
     output.copyTo(blurredBitmap); 

     source.recycle(); 
     return blurredBitmap; 
    } 

    @Override 
    public String key() { 
     return "blurred"; 
    } 
} 

Dopo aver aggiunto questa classe utilizzare il Picasso per sfocare l'imageview o qualsiasi bitmap

Picasso.with(context).load("load-from-whatever-source").transform(new Blur(context, 20)).into("wherever"); 

ho trovato questa risposta in this blog.

+0

Mentre questo link può rispondere alla domanda, è meglio includere qui le parti essenziali della risposta e fornire il link per riferimento. Le risposte di solo collegamento possono diventare non valide se la pagina collegata cambia. – Samurai

+0

@Samurai Sì, hai ragione. Grazie. Modificherò la mia risposta. Si prega di valutare :) –

+1

Questo codice non funziona sull'ultima versione di Picasso, la riga: 'blurredBitmap = Bitmap.createBitmap (sourceBitmap);' deve essere sostituito con 'blurredBitmap = source.copy (source.getConfig(), true) ; ' – Franco

Problemi correlati