0

I'm working with Android SDK for IoT camera. I want to implement taking snapshots from the camera and save it to the external storage. SDK provides a method for that which takes absoluteFilePath as a parameter.

int snapshot(String absoluteFilePath, Context context, OperationDelegateCallBack callBack);

Unfortunately because of scope storage introduced in Android 10 this method is not working. There is info that If I want to use scope storage I need to implement this feature by myself. In this case, I need to get raw frame data in YUV420SP (NV21) format. SDK provides callback for that:

fun onReceiveFrameYUVData(
            sessionId: Int,
            y: ByteBuffer,
            u: ByteBuffer,
            v: ByteBuffer,
            videoFrameInfo: TuyaVideoFrameInfo?,
            camera: Any?,
        )

I would like to use YuvImage class from android graphics package to convert this image to JPEG (it provides method compressToJpeg). Constructor of that class takes only a single byte array as a parameter. Callback from SDK provides YUV components as separate buffers. How should I concat those three buffers into one array to use YuvImage class?

BTW Is this the proper approach or maybe should I use something else?

SDK documentation: https://developer.tuya.com/en/docs/app-development/avfunction?id=Ka6nuvucjujar#title-3-Video%20screenshots

Zygi
  • 754
  • 8
  • 17
  • There is OpenGL functionality which is able to do conversion directly to screen. Since this is made by hardware this the only way to not kill performance. Now I can't provide specific name (i did this +5 years ego), but this should help you to google proper solution. – Marek R Jan 16 '23 at 10:55
  • Does this answer your question? [Using opengl es shader to convert YUV to RGB](https://stackoverflow.com/questions/17105386/using-opengl-es-shader-to-convert-yuv-to-rgb) – Marek R Jan 16 '23 at 10:57
  • Thank you for your comment @Marek R. Do I really need to use OpenGL to convert single frame into a bitmap? I don't want to convert video stream, I just need one frame. – Zygi Jan 16 '23 at 11:04
  • If you have one frame only it is not required, but recommended. This simple task for high resolution image is quite demanding for CPU. If you google topic properly I'm sure you will find ready solution for android and Kotlin. – Marek R Jan 16 '23 at 11:09

1 Answers1

0

Unfortunately because of scope storage introduced in Android 10 this method is not working.

Of course it still works if you use a normal writable and readable full path.

For Android 10 you dont have to change your usual path. (I do not understand that you have any problem there).

For Android 11+ use public image directories like DCIM and Pictures.

blackapps
  • 8,011
  • 2
  • 11
  • 25
  • Yes, scope storage is required since Android 11+. On Android 10 you can use legacy access. Anyway even if I provide an absolute file path `snapshot()` method returns an error. Even documentation stands that it will not work. I can use scope storage and public directories to save an image, but first I need to have an image :D The snapshot method doesn't provide one, so that's why I need to extract it from the frame. – Zygi Jan 16 '23 at 11:30
  • Which absolute path do you provide? I told you to use those public directories. I do not understand what you mean with not provide one.. CompressToJpeg can compress to those public directories. – blackapps Jan 16 '23 at 11:31
  • As in the documentation (https://developer.tuya.com/en/docs/app-development/avfunction?id=Ka6nuvucjujar#title-3-Video%20screenshots), I use: `Environment.getExternalStorageDirectory().absolutePath + "/MyApp/"`. But It's a solution for Android <11 – Zygi Jan 16 '23 at 11:35
  • That is not an existing directory like DCIM or Pictures. And you cannot crerate your own directories at root of external storqage on Android 11+ devices. Make it DCIM/MyApp or Pictures/MyApp. – blackapps Jan 16 '23 at 11:37
  • `File myDir = new File (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "MyApp");` – blackapps Jan 16 '23 at 11:38
  • That documentation is wrong and a shame for not checking the return value of mkdir as it fails on Android 11+ always. – blackapps Jan 16 '23 at 11:43
  • Wow, mate you are right! Using this public pictures folder works perfectly fine :D – Zygi Jan 16 '23 at 11:52