2014-02-15 7 views
5

Ich habe eine Demo-Anwendung erstellt, die die Kamera öffnet.nun möchte ich die Farbe des Pixels erhalten, wenn der Benutzer die Live-Kamera Vorschau berührt.Get Farbe der berührten Pixel aus der Kamera Vorschau

Ich habe versucht, durch onTouchEvent überschrieben und es mir gelingt, in getting the position of pixel in x, y but Ich bin nicht der RGB color value von it.it bekommen immer 0,0,0 zeigt

Alle Vorschläge einschließlich alternative Art und Weise begrüßt werden, um die gleiche Funktionalität zu erreichen . [Excluding OpenCv because it requires to install OpenCvManager apk also to support my application]

Code:

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback, PreviewCallback { 

    private Camera camera; 
    private SurfaceHolder holder; 
    int[] myPixels; 

    public CameraPreview(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    public CameraPreview(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public CameraPreview(Context context) { 
     super(context); 
    } 

    public void init(Camera camera) { 
     this.camera = camera; 
     initSurfaceHolder(); 
    } 

    @SuppressWarnings("deprecation") // needed for < 3.0 
    private void initSurfaceHolder() { 
     holder = getHolder(); 
     holder.addCallback(this); 
     holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     initCamera(holder); 
    } 

    private void initCamera(SurfaceHolder holder) { 
     try { 
      camera.setPreviewDisplay(holder); 
      camera.getParameters().setPreviewFormat(ImageFormat.NV21); 
      camera.setPreviewCallback(this); 
      camera.startPreview(); 
     } catch (Exception e) { 
      Log.d("Error setting camera preview", e); 
     } 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     if(event.getAction() == MotionEvent.ACTION_DOWN) 
     { 
      android.util.Log.d("touched", "called"); 
/*   int x = (int)event.getX(); 
      int y = (int)event.getY(); 

      android.util.Log.d("touched pixel :", x+" "+y); 

      setDrawingCacheEnabled(true); 
      buildDrawingCache(); 
      Bitmap mBmp = getDrawingCache(); 

      int pixel = mBmp.getPixel(x, y); 
      int redValue = Color.red(pixel); 
      int blueValue = Color.blue(pixel); 
      int greenValue = Color.green(pixel);   

      android.util.Log.d("touched pixel color :", redValue+" "+greenValue+" "+blueValue); 
      android.util.Log.d("touched pixel color from preview:", redValue+" "+greenValue+" "+blueValue); 
*/ 
      //how to get particular pixel from myPixels[] 
     } 
     return false; 
    } 

    @Override 
    public void onPreviewFrame(byte[] data, Camera camera) { 

     android.util.Log.d("onPreviewFrame", "called"); 

     int frameHeight = camera.getParameters().getPreviewSize().height; 
      int frameWidth = camera.getParameters().getPreviewSize().width; 
      // number of pixels//transforms NV21 pixel data into RGB pixels 
      int rgb[] = new int[frameWidth * frameHeight]; 
      // convertion 
      myPixels = decodeYUV420SP(rgb, data, frameWidth, frameHeight); 

    } 



    public int[] decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) { 

     // here we're using our own internal PImage attributes 
     final int frameSize = width * height; 

     for (int j = 0, yp = 0; j < height; j++) { 
       int uvp = frameSize + (j >> 1) * width, u = 0, v = 0; 
       for (int i = 0; i < width; i++, yp++) { 
         int y = (0xff & ((int) yuv420sp[yp])) - 16; 
         if (y < 0) 
           y = 0; 
         if ((i & 1) == 0) { 
           v = (0xff & yuv420sp[uvp++]) - 128; 
           u = (0xff & yuv420sp[uvp++]) - 128; 
         } 

         int y1192 = 1192 * y; 
         int r = (y1192 + 1634 * v); 
         int g = (y1192 - 833 * v - 400 * u); 
         int b = (y1192 + 2066 * u); 

         if (r < 0) 
           r = 0; 
         else if (r > 262143) 
           r = 262143; 
         if (g < 0) 
           g = 0; 
         else if (g > 262143) 
           g = 262143; 
         if (b < 0) 
           b = 0; 
         else if (b > 262143) 
           b = 262143; 

         // use interal buffer instead of pixels for UX reasons 
         rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) 
             | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff); 
       } 
     } 

     return rgb; 
} 


} 
+1

Versuchen Sie, den Code von hier http://StackOverflow.com/q/15918180/1069068 –

+0

@RaghavSood: Ich habe es durchlaufen, aber soweit ich das verstehe, wird die Methode 'onPreviewFrame' kontinuierlich.won ausgeführt werden ist es schwer auf dem Gerät? und ja, ich habe es in meinen Code aufgenommen, wie bekomme ich eine bestimmte Pixelfarbe aus dem Array 'myPixels'? –

Antwort

3

Ich habe einen anderen Ansatz verfolgt, es zu lösen. Ich poste den Code, sobald ich frei bin.

Algorithm : 
  • erstellen einen Overlay auf der Live-Kamera
  • , wenn der Benutzer berührt, aktualisieren Sie die Overlay mit RGB-Daten des letzten Stream YUV Puffers bekam von Live-Kamera
  • Pick-RGB-Farb von Overlay-Bild
+2

Könnten Sie bitte den Code posten? Vielen Dank! –

3

Es ist wie myPixels scheint, ist eine 1D-Darstellung von 2D-Daten (Breite x Höhe).

Welche myPixels bedeutet, hat eine Länge von (Breite * Höhe).

Nehmen wir das Pixel (x, y) dann

int idx = (height * y) + x; 

int color = myPixels[idx]; 

Mit der obigen Informationen decodeYUV420SP Verfahren zur Ausgabe ändern können nur die Farbe eines bestimmten Pixels.

+0

es ist nicht zu erwarten Versehen Farbe wie output.because den widthxheight von 'SurfaceView' und' frameSize' der Kameravorschau ist anders. –

+0

kennen Sie einen alternativen Weg, um dies zu erreichen? Ich habe nichts dagegen, auch jede 3rd-Party-Bibliothek –

+0

Ich habe keine Bibliotheken anzutreffen, die dieses Problem lösen. Ich denke, dass eine gewisse Verrechnung (x, y) das Problem lösen wird. Aber hat es nicht herausgefunden – Josnidhin