2016-04-27 4 views
0

Моя цель - добавить наложение на предварительный просмотр камеры, который найдет края книги. Для этого я переопределить onPreviewFrame где я сделать следующее:Android opencv byte [] to mat to byte []

public void onPreviewFrame(byte[] data, Camera camera) { 
     Camera.Parameters parameters = camera.getParameters(); 
     int width = parameters.getPreviewSize().width; 
     int height = parameters.getPreviewSize().height; 
     Mat mat = new Mat((int) (height*1.5), width, CvType.CV_8UC1); 
     mat.put(0,0,data); 
     byte[] bytes = new byte[(int) (height*width*1.5)]; 
     mat.get(0,0,bytes); 

     if (!test) {  //to only do once 
      File pictureFile = getOutputMediaFile(); 
      try { 
       FileOutputStream fos = new FileOutputStream(pictureFile); 
       fos.write(bytes); 
       fos.close(); 
       Uri picUri = Uri.fromFile(pictureFile); 
       updateGallery(picUri); 
       test = true; 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

Сейчас я просто хочу, чтобы занять одно из предварительных просмотров и сохранить его после преобразования в мат.

Проведя бесчисленное количество часов, чтобы посмотреть выше, сохраненное изображение не может быть видно на моем тестовом телефоне (LG Leon). Кажется, я не могу найти проблему. Я смешиваю высоту/ширину, потому что я фотографирую в портретном режиме? Я попытался переключить их и до сих пор не работает. В чем проблема?

ответ

0

Кажется весьма неэффективно, но это работает для меня (на данный момент):

//get the camera parameters 
Camera.Parameters parameters = camera.getParameters(); 
int width = parameters.getPreviewSize().width; 
int height = parameters.getPreviewSize().height; 

//convert the byte[] to Bitmap through YuvImage; 
//make sure the previewFormat is NV21 (I set it so somewhere before) 
YuvImage yuv = new YuvImage(data, parameters.getPreviewFormat(), width, height, null); 
ByteArrayOutputStream out = new ByteArrayOutputStream(); 
yuv.compressToJpeg(new Rect(0, 0, width, height), 70, out); 
Bitmap bmp = BitmapFactory.decodeByteArray(out.toByteArray(), 0, out.size()); 

//convert Bitmap to Mat; note the bitmap config ARGB_8888 conversion that 
//allows you to use other image processing methods and still save at the end 
Mat orig = new Mat(); 
bmp = bmp.copy(Bitmap.Config.ARGB_8888, true); 
Utils.bitmapToMat(bmp, orig); 

//here you do whatever you want with the Mat 

//Mat to Bitmap to OutputStream to byte[] to File 
Utils.matToBitmap(orig, bmp); 
ByteArrayOutputStream stream = new ByteArrayOutputStream(); 
bmp.compress(Bitmap.CompressFormat.JPEG, 70, stream); 
byte[] bytes = stream.toByteArray(); 
File pictureFile = getOutputMediaFile(); 
try { 
    FileOutputStream fos = new FileOutputStream(pictureFile); 
    fos.write(bytes); 
    fos.close(); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 
0

Самый быстрый способ, который мне удалось найти, описан HERE в моем недавно заданном вопросе. Вы можете найти способ извлечения изображения в ответе, который я написал в моем вопросе ниже. Дело в том, что изображение, которое вы получаете через onPreviewFrame(), - NV21. После получения этого изображения может оказаться, что вам нужно преобразовать его в RGB (в зависимости от того, чего вы хотите достичь, это также делается в ответе, который я дал вам ранее).

+0

Смешные достаточно, один из моих конечных целей такой же, как у вас: чтобы отобразить прямоугольники вокруг текста в режиме реального времени. Я попробую использовать ваш ответ и посмотреть, куда он идет. благодаря! – Dimebag