【YUV420转RGB】------C(java)语言与neon优化

I420转RGB

一.【java实现】

 public static int[] yuvI420toARGB(byte[] i420, int width, int height) {
        int framesize = width * height;

        int[] rgb = new int[framesize];//新图大小
        for (int i = 0; i < framesize; i++) {
            int index = (i / width) / 2 * (width / 2) + (i % width) / 2;
            int y = i420[i] & 0x000000ff;//i420 y分量的值大小是一个字节,准换成int
            int u = i420[framesize + index] & 0x000000ff;//i420 u分量
            int v = i420[framesize + framesize / 4 + index] & 0x000000ff;//i420 v

            /*yuv----rgb 转换公式*/
            int b = (int) (y + 1.8556 * (u - 128));
            int g = (int) (y - (0.4681 * (v - 128) + 0.1872 * (u - 128)));
            int r = (int) (y + 1.5748 * (v - 128));
            /*防止越界*/
            b=(b>255)?255:((b<0)?0:b);
            g=(g>255)?255:((g<0)?0:g);
            r=(r>255)?255:((r<0)?0:r);
            rgb[i] = (0xff000000) | (0x00ff0000 & r << 16) | (0x0000ff00 & g << 8) | (0x000000ff & b);
        }
        return rgb;

    }

调用与验证

1.读取实例文件

AssetManager assetManager = this.getAssets();
            try {
                
                InputStream inputStream = assetManager.open("1280x960_0.i420");//filename是assets目录下的图片名
                /////////////////////////////////////////////
                /*inputStream流转化为bute[]流*/
                str=readStream (inputStream);
                int width,height;
                width=1280;height=960;
                /////////////////////////////////////////////
                /*转换函数的调用*/
                ints=yuvI420toARGB(str,width,height);
                /////////////////////////////////////////////
                /*创建一个位图对象,将转换的数据导入*/
                test=Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
                test.setPixels(ints,0,width,0,0,width,height);
                ///////////////////////////////////////////////
                if(test==null)
                    Log.d("Bitmap","Test Error!");
            } catch (IOException e) {
                e.printStackTrace();
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            iv_dst.setImageBitmap(test);//位图显示
           ////////////////////////////////////
           /*将图像保存到图库*/
            saveMyBitmap(test);

2.将读取的文件转换为byte流

 public static byte[] readStream(InputStream inStream) throws Exception {
        byte[] buffer = new byte[1024];
        int len = -1;
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        while ((len = inStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, len);
        }
        byte[] data = outStream.toByteArray();
        outStream.close();
        inStream.close();
        return data;
    }

3.保存转换后的图像

private void saveMyBitmap(Bitmap bitmap) {

        File sd = Environment.getExternalStorageDirectory();

        File destDir = new File(sd.getPath() + "/DCIM/" + "Camera/");
        if (!destDir.exists()) {
            destDir.mkdirs();
        }
        long currentTime = System.currentTimeMillis();

        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");

        Date date = new Date(currentTime);

        String str1=formatter.format(date);

        String tmpfile = sd.getPath() + "/DCIM/" + "Camera/" + str1 + ".jpg";

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            //申请WRITE_EXTERNAL_STORAGE权限
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},0);
        }
        Log.e("TAG", tmpfile);
        BufferedOutputStream bos = null;
        try {
            try {
                bos = new BufferedOutputStream(new FileOutputStream(tmpfile));
                if(bos==null)
                    Log.e("TAG", "bos is null");
                else
                    Log.e("TAG", "bos is not null");
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                Log.e("TAG", "catch");
                e.printStackTrace();
            }
            bitmap.compress(Bitmap.CompressFormat.JPEG, 90, bos);
           // bitmap.recycle();
        } catch (Exception e) {
            Log.e("TAG", "截屏失败");
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            if (bos != null)
                try {
                    bos.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }
        // 最后通知图库更新
        sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + tmpfile)));

    }

二.【使用NEON进行优化】

你可能感兴趣的:(【YUV420转RGB】------C(java)语言与neon优化)