2013-09-20 3 views
12

Я хочу изменить область сканирования камеры. Теперь я беру изображение для сканирования размером с экран устройства. Я пытаюсь обрезать изображение для анализа. Таким образом, только центр предварительного просмотра будет источником сканирования. Есть ли возможность установить захваченный предварительный просмотр меньшим или создать Bitmap из данных byte [] и обрезать, это единственный способ получить меньшую площадь? Я пытался что-то прочитать, но документация для Zbar Android очень плохая (по сравнению с iOS).Как изменить область сканирования Zbar?

Картина здесь: http://postimg.org/image/4wk4u0mln/

MainActivity

public class MainActivity extends Activity 
{ 
    private Camera mCamera; 
    private Context context; 
    private CameraPreview mPreview; 
    private Handler autoFocusHandler; 

    TextView scanText; 
    Button scanButton; 

    ImageScanner scanner; 
    private PowerManager.WakeLock wl; 

    private boolean barcodeScanned = false; 
    private boolean previewing = true; 

    static { 
     System.loadLibrary("iconv"); 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 



     setContentView(R.layout.activity_main); 

     setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); 

     autoFocusHandler = new Handler(); 
     mCamera = getCameraInstance(); 


     context = getApplicationContext(); 

     /* Instance barcode scanner */ 
     scanner = new ImageScanner(); 

     scanner.setConfig(0, Config.X_DENSITY, 3); 
     scanner.setConfig(0, Config.Y_DENSITY, 3); 

     mPreview = new CameraPreview(this, mCamera, previewCb, autoFocusCB); 
     FrameLayout preview = (FrameLayout)findViewById(R.id.cameraPreview); 
     preview.addView(mPreview); 

     scanText = (TextView)findViewById(R.id.scanText); 


    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     releaseCamera(); 
    } 

    @Override 
    protected void onResume() { 
     // TODO Auto-generated method stub 

     onStart(); 
    } 

    @Override 
    protected void onStop() { 
     // TODO Auto-generated method stub 
     super.onStop(); 

     finish(); 
    } 

    /** A safe way to get an instance of the Camera object. */ 
    public static Camera getCameraInstance(){ 
     Camera c = null; 
     try { 
      c = Camera.open(); 
     } catch (Exception e){ 
     } 
     return c; 
    } 

    private void releaseCamera() { 
     if (mCamera != null) { 
      previewing = false; 
      mCamera.setPreviewCallback(null); 
      mCamera.release(); 
      mCamera = null; 
     } 
    } 

    private Runnable doAutoFocus = new Runnable() { 
      @Override 
      public void run() { 
       if (previewing) 
        mCamera.autoFocus(autoFocusCB); 
      } 
     }; 

    PreviewCallback previewCb = new PreviewCallback() { 
      @Override 
      public void onPreviewFrame(byte[] data, Camera camera) { 
       Camera.Parameters parameters = camera.getParameters(); 
       Size size = parameters.getPreviewSize(); 
       //HERE we read taken picture from prieview 
       Image barcode = new Image(size.width, size.height, "Y800"); 

       barcode.setData(data); 


       int result = scanner.scanImage(barcode); 

       if (result != 0) { 
        previewing = false; 
        mCamera.setPreviewCallback(null); 


        mCamera.stopPreview(); 



        SymbolSet syms = scanner.getResults(); 
        for (Symbol sym : syms) { 

        if (sym.getType() == Symbol.CODE128) { 
         sym.getData()); 
         MediaPlayer mp = MediaPlayer.create(context, R.raw.beep_ok); 
         mp.start(); 


        } else { 

         MediaPlayer mp = MediaPlayer.create(context, R.raw.beep_wrong); 
         mp.start(); 
        } 


         mCamera.setPreviewCallback(previewCb); 
         mCamera.startPreview(); 
         previewing = true; 
         mCamera.autoFocus(autoFocusCB); 



        } 
       } 
      } 
     }; 

    // Mimic continuous auto-focusing 
    AutoFocusCallback autoFocusCB = new AutoFocusCallback() { 
      @Override 
      public void onAutoFocus(boolean success, Camera camera) { 
       autoFocusHandler.postDelayed(doAutoFocus, 1000); 
      } 
     }; 


     //Method to crop Bitmap in case of use 
     public Bitmap scaleCenterCrop(Bitmap source, int newHeight, int newWidth) { 
      int sourceWidth = source.getWidth(); 
      int sourceHeight = source.getHeight(); 

      float xScale = (float) newWidth/sourceWidth; 
      float yScale = (float) newHeight/sourceHeight; 
      float scale = Math.max(xScale, yScale); 

      float scaledWidth = scale * sourceWidth; 
      float scaledHeight = scale * sourceHeight; 

      float left = (newWidth - scaledWidth)/2; 
      float top = (newHeight - scaledHeight)/2; 

      RectF targetRect = new RectF(left, top, left + scaledWidth, top + scaledHeight); 


      Bitmap dest = Bitmap.createBitmap(newWidth, newHeight, source.getConfig()); 
      Canvas canvas = new Canvas(dest); 
      canvas.drawBitmap(source, null, targetRect, null); 

      return dest; 
     } 

} 

CameraPrieview.java

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback { 
    private SurfaceHolder mHolder; 
    private Camera mCamera; 
    private PreviewCallback previewCallback; 
    private AutoFocusCallback autoFocusCallback; 

    public CameraPreview(Context context, Camera camera, 
         PreviewCallback previewCb, 
         AutoFocusCallback autoFocusCb) { 
     super(context); 
     mCamera = camera; 
     previewCallback = previewCb; 
     autoFocusCallback = autoFocusCb; 

     /* 
     * Set camera to continuous focus if supported, otherwise use 
     * software auto-focus. Only works for API level >=9. 
     */ 
     /* 
     Camera.Parameters parameters = camera.getParameters(); 
     for (String f : parameters.getSupportedFocusModes()) { 
      if (f == Parameters.FOCUS_MODE_CONTINUOUS_PICTURE) { 
       mCamera.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); 
       autoFocusCallback = null; 
       break; 
      } 
     } 
     */ 

     // Install a SurfaceHolder.Callback so we get notified when the 
     // underlying surface is created and destroyed. 
     mHolder = getHolder(); 
     mHolder.addCallback(this); 

     // deprecated setting, but required on Android versions prior to 3.0 
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     // The Surface has been created, now tell the camera where to draw the preview. 
     try { 
      mCamera.setPreviewDisplay(holder); 
     } catch (IOException e) { 
      Log.d("DBG", "Error setting camera preview: " + e.getMessage()); 
     } 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     // Camera preview released in activity 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
     /* 
     * If your preview can change or rotate, take care of those events here. 
     * Make sure to stop the preview before resizing or reformatting it. 
     */ 
     if (mHolder.getSurface() == null){ 
      // preview surface does not exist 
      return; 
     } 

     // stop preview before making changes 
     try { 
      mCamera.stopPreview(); 
     } catch (Exception e){ 
      // ignore: tried to stop a non-existent preview 
     } 

     try { 
      // Hard code camera surface rotation 90 degs to match Activity view in portrait 
      mCamera.setDisplayOrientation(90); 

      mCamera.setPreviewDisplay(mHolder); 
      mCamera.setPreviewCallback(previewCallback); 
      mCamera.startPreview(); 
      mCamera.autoFocus(autoFocusCallback); 
     } catch (Exception e){ 
      Log.d("DBG", "Error starting camera preview: " + e.getMessage()); 
     } 
    } 
} 
+1

Hi пользователь2245026! Я ищу то же самое. У вас было какое-то возможное решение для этого. –

ответ

19

В PreviewCallback вы можете обрезать область сканирования. В методе onPreviewFrame после вызова barcode.setData() вы можете позвонить barcode.setCrop (слева, сверху, ширине, высоте). Все измерения в пикселях.
Также не забудьте установить размер обрезки относительно размера изображения предварительного просмотра, а не размера экрана устройства.

Примечание: Пожалуйста, убедитесь, что ось х всегда является самой длинной стороной, даже если вы ориентируете телефон в портретном режиме. Пожалуйста, обратитесь к рисунку ниже, чтобы лучше понять аргументы.

Это решение относится к zbar для Android.

illustration of of scanning area in zbar

+2

Привет, вы знаете, как определяются левые/верхние/ширина/высота? Являются ли они процентами размера экрана или пикселей? –

+1

Каково измерение каждого параметра? Есть ли это? или пиксель? или еще? – poring91

+2

@ poring91 - Все измерения находятся в пикселях. Я отредактировал ответ с помощью единиц. – Dilip

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