YV12转RGB24\IplImage 转BufferedImage

 
org.bytedeco.javacpp版本3.4存在问题,需使用低版本。
package cn.edu.xiyou.hikvision;

import org.bytedeco.javacpp.BytePointer;

import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;

import static org.bytedeco.javacpp.opencv_core.*;

public class YV12RGB24Convert {
    private byte[] YV12_To_RGB24(byte[] yv12, int width, int height) {
        if (yv12 == null) {
            return null;
        }

        int nYLen = (int) width * height;
        int halfWidth = width >> 1;

        if (nYLen < 1 || halfWidth < 1) {
            return null;
        }

        // yv12's data structure
        // |WIDTH |
        // y......y--------
        // y......y   HEIGHT
        // y......y
        // y......y--------
        // v..v
        // v..v
        // u..u
        // u..u

        // Convert YV12 to RGB24
        byte[] rgb24 = new byte[width * height * 3];
        int[] rgb = new int[3];
        int i, j, m, n, x, y;
        m = -width;
        n = -halfWidth;
        for (y = 0; y < height; y++) {
            m += width;
            if (y % 2 != 0) {
                n += halfWidth;
            }

            for (x = 0; x < width; x++) {
                i = m + x;
                j = n + (x >> 1);
                rgb[2] = (int) ((int) (yv12[i] & 0xFF) + 1.370705 * ((int) (yv12[nYLen + j] & 0xFF) - 128)); // r
                rgb[1] = (int) ((int) (yv12[i] & 0xFF) - 0.698001 * ((int) (yv12[nYLen + (nYLen >> 2) + j] & 0xFF) - 128) - 0.703125 * ((int) (yv12[nYLen + j] & 0xFF) - 128));   // g
                rgb[0] = (int) ((int) (yv12[i] & 0xFF) + 1.732446 * ((int) (yv12[nYLen + (nYLen >> 2) + j] & 0xFF) - 128)); // b

                //j = nYLen - iWidth - m + x;
                //i = (j<<1) + j;    //图像是上下颠倒的

                j = m + x;
                i = (j << 1) + j;

                for (j = 0; j < 3; j++) {
                    if (rgb[j] >= 0 && rgb[j] <= 255) {
                        rgb24[i + j] = (byte) rgb[j];
                    } else {
                        rgb24[i + j] = (byte) ((rgb[j] < 0) ? 0 : 255);
                    }
                }
            }
        }

        return rgb24;
    }

    public IplImage YV12_ToIplImage(byte[] yv12, int width, int height) {
        if (yv12 == null) {
            return null;
        }

        byte[] rgb24 = YV12_To_RGB24(yv12, width, height);
        if (rgb24 == null) {
            return null;
        }
        //测试写出文件正确  2018年3月24日10:51:13
        //        try {
        //            FileOutputStream f = new FileOutputStream("d:/picTest/picTestOut/" + System.currentTimeMillis() + ".jpg");
        //            f.write(rgb24);
        //            f.flush();
        //            f.close();
        //        } catch (java.io.IOException e) {
        //            e.printStackTrace();
        //        }

        CvSize cd = cvSize(width, height);
        IplImage image = cvCreateImage(cvSize(width, height), 8, 3);
        image.imageData(new BytePointer(rgb24));
//        System.out.println(image.width());

        return image;
    }

    /**
     * 功能说明:将javacv的IplImage图像转为java 2d自身的BufferedImage
     *
     * @param iplImage javacv图像
     * @return BufferedImage
     * java 2d图像
     * @time:2018年3月24日11:46:02
     * @author:lyf
     * @exception:
     */
    public BufferedImage iplToBufImgData(IplImage iplImage) {
        if (iplImage.height() > 0 && iplImage.width() > 0) {
            BufferedImage image = new BufferedImage(iplImage.width(), iplImage.height(),
                    BufferedImage.TYPE_3BYTE_BGR);
            WritableRaster raster = image.getRaster();
            DataBufferByte dataBuffer = (DataBufferByte) raster.getDataBuffer();
            byte[] data = dataBuffer.getData();
            iplImage.getByteBuffer().get(data);

//            try {
//                ImageIO.write(image, "jpg", new File("d:/picTest/picTestOut/" + System.currentTimeMillis() + ".jpg"));
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
            return image;
        }
        return null;
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

新思维软件

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值