uvcCamera设置setFrameCallback获取流转位图Bitmap

 /**
     * 打开相机 如果只有一个UsbDevice就不用加设备判断 
     */
    fun open(activity: Activity, surfaceView: AspectRatioSurfaceView) {
        mActivity = activity
        try {
            mCameraHelper = CameraHelper()

            //UVC摄像头状态回调
            mStateListener = object : ICameraHelper.StateCallback {
                //插入UVC设备
                override fun onAttach(device: UsbDevice) {
                    //设置为当前设备(如果没有权限,会显示授权对话框)
                    if (mUsbDevice != null && device == mUsbDevice) {
                        mCameraHelper?.selectDevice(device)
                    }
                }

                //打开UVC设备成功(也就是已经获取到UVC设备的权限)
                override fun onDeviceOpen(device: UsbDevice, isFirstOpen: Boolean) {
                    //打开UVC摄像头
                    if (mUsbDevice != null && device == mUsbDevice) {
                        mCameraHelper?.openCamera()
                    }
                }

                //打开摄像头成功
                override fun onCameraOpen(device: UsbDevice) {
                    if (mUsbDevice != null && device == mUsbDevice) {
                        //开始预览
                        mCameraHelper?.startPreview()
//                    //需要自适应摄像头分辨率的话,设置新的宽高比
//                    surfaceView.setAspectRatio(640, 480)
                        //获取预览使用的Size(包括帧格式、宽度、高度、FPS)
                        val size = mCameraHelper?.getPreviewSize()
                        if (size != null) {
                            val width = size.width
                            val height = size.height
                            //需要自适应摄像头分辨率的话,设置新的宽高比
                            surfaceView.setAspectRatio(width, height)
                        }

                        //添加预览Surface
                        mCameraHelper?.addSurface(surfaceView.holder.surface, false)

                       
                            mCameraHelper?.setFrameCallback(IFrameCallback {
                               var mFrame = bytebuffer2ByteArray(it)
                                //这是成像代码。可以在需要的地方调用
                               nv21ToBitmap(activity,mFrame,width,height)
              //如果是YUV格式请看最下面的一个java方法,参数为PIXEL_FORMAT_YUV
                            }, UVCCamera.PIXEL_FORMAT_NV21)
                        
                    }
                }

                //关闭摄像头成功
                override fun onCameraClose(device: UsbDevice) {
                    //移除预览Surface 已经在surfaceView的surfaceDestroyed方法里调用过了
                    //官方的案例这里会再次removeSurface导致了再次打开相机会出现异常
                }

                //关闭UVC设备成功
                override fun onDeviceClose(device: UsbDevice) {
                    Timber.d("USB相机关闭成功")
                }

                //断开UVC设备
                override fun onDetach(device: UsbDevice) {
                    Timber.d("USB相机断开连接:${device.productName}")
                }

                //用户没有授予访问UVC设备的权限
                override fun onCancel(device: UsbDevice) {}
            }
            //设置SurfaceView的Surface监听回调
            surfaceView.holder.addCallback(object : SurfaceHolder.Callback {
                //创建了新的Surface
                override fun surfaceCreated(holder: SurfaceHolder) {
                    //添加预览Surface
                    mCameraHelper?.addSurface(holder.surface, false)
                }

                //Surface发生了改变
                override fun surfaceChanged(
                    holder: SurfaceHolder,
                    format: Int,
                    width: Int,
                    height: Int
                ) {
                }

                //销毁了原来的Surface
                override fun surfaceDestroyed(holder: SurfaceHolder) {
                    //移除预览Surface
                    try {
                        mCameraHelper?.removeSurface(holder.surface)
                    } catch (_: Exception) {
                    }
                }
            })
            //设置UVC摄像头状态回调
            mCameraHelper?.setStateCallback(mStateListener)
        } catch (e: Exception) {
            //普通相机通信异常
           
        }
    }

  fun bytebuffer2ByteArray(buffer: ByteBuffer): ByteArray? {
        //重置 limit 和postion 值
        // buffer.flip();
        //获取buffer中有效大小
        val len: Int = buffer.limit() - buffer.position()
        val bytes = ByteArray(len)
        for (i in bytes.indices) {
            bytes[i] = buffer.get()
        }
        return bytes
    }

//2毫秒左右转换完成
   fun nv21ToBitmap(context: Context, nv21: ByteArray, width: Int, height: Int): Bitmap? {
        val rs = RenderScript.create(context)
        val yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs))
        var yuvType: Type.Builder? = null
        yuvType = Type.Builder(rs, Element.U8(rs)).setX(nv21.size)
        val `in` = Allocation.createTyped(rs, yuvType.create(), 1)
        val rgbaType = Type.Builder(rs, Element.RGBA_8888(rs)).setX(width).setY(height)
        val out = Allocation.createTyped(rs, rgbaType.create(), 1)
        `in`.copyFrom(nv21)
        yuvToRgbIntrinsic.setInput(`in`)
        yuvToRgbIntrinsic.forEach(out)
        val bmpout = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        out.copyTo(bmpout)
        return bmpout
    }

 public Bitmap yuv2Bmp(byte[] data, int width, int height) {
        ByteArrayOutputStream baos;
        byte[] rawImage;
        Bitmap bitmap;
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        newOpts.inJustDecodeBounds = true;
        YuvImage yuvimage = new YuvImage(
                data,
                ImageFormat.NV21,
                width,
                height,
                null);
        baos = new ByteArrayOutputStream();
        yuvimage.compressToJpeg(new Rect(0, 0, width, height), 100, baos);
        rawImage = baos.toByteArray();
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        bitmap = BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length, options);
        return bitmap;
    }

以上注意setFrameCallback只能在startPreview、addSurface之后调用,不按顺序调用就接受不到回调!

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
位图Bitmap)是一种用于表示图像的数据结构,也是图形图像处理的基础。它是由像素点(Pixel)组成的矩阵,每个像素点用二进制数表示其对应的颜色,通常一个像素点占用一个或多个字节的存储空间。 在Java中,可以通过java.awt.image.BufferedImage类实现位图的创建和编辑。下面是一个简单的Java代码示例,用于创建一张黑色背景、红色前景的位图,并将其保存为文件: ```java import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO; public class BitmapExample { public static void main(String[] args) { int width = 256; int height = 256; BufferedImage bitmap = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = bitmap.getGraphics(); g.setColor(Color.BLACK); g.fillRect(0, 0, width, height); g.setColor(Color.RED); g.fillOval(64, 64, 128, 128); g.dispose(); try { ImageIO.write(bitmap, "bmp", new File("example.bmp")); } catch (Exception e) { e.printStackTrace(); } } } ``` 在上面的代码中,我们首先创建了一个宽度和高度均为256像素的位图,然后使用Graphics对象绘制了一个黑色背景和一个红色的圆形。最后,我们将位图保存为一个bmp格式的文件,以便在其他应用程序中使用。 除了BufferedImage类外,还有许多其他的Java图像处理库和工具,如ImageJ、JAI、JavaFX等,它们都提供了不同程度的位图编辑和处理功能,可以根据具体需求选择适合自己的工具。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值