whycxzp
2024-07-27 efa5fe48ebc866ec07a597ef551cf7e13c3b7aba
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
package com.whyc.util;
 
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Locale;
 
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
//import android.support.media.ExifInterface;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.media.ExifInterface;
import android.media.Image;
import android.os.Environment;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicYuvToRGB;
 
import static android.os.Environment.DIRECTORY_DOCUMENTS;
 
public class BitmapUtil {
 
    // 把位图对象保存为指定路径的图片文件
    public static void saveBitmap(String path, Bitmap bitmap, String format, int quality) {
        Bitmap.CompressFormat compressFormat = Bitmap.CompressFormat.JPEG;
        if (format.toUpperCase(Locale.getDefault()).equals("PNG")) {
            compressFormat = Bitmap.CompressFormat.PNG;
        }
        try {
            // 根据指定文件路径构建缓存输出流对象
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path));
            // 把位图数据压缩到缓存输出流中
            bitmap.compress(compressFormat, quality, bos);
            // 完成缓存输出流的写入动作
            bos.flush();
            // 关闭缓存输出流
            bos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    // 把位图数据保存到指定路径的图片文件
    public static void saveBitmap(String path, ByteBuffer buffer,
                                  int sample_size, String format, int quality) {
        try {
            byte[] buff = new byte[buffer.remaining()];
            buffer.get(buff);
            BitmapFactory.Options ontain = new BitmapFactory.Options();
            ontain.inSampleSize = sample_size;
            Bitmap bitmap = BitmapFactory.decodeByteArray(buff, 0, buff.length, ontain);
            saveBitmap(path, bitmap, format, quality);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    // 从指定路径的图片文件中读取位图数据
    public static Bitmap openBitmap(String path) {
        Bitmap bitmap = null;
        try {
            // 根据指定文件路径构建缓存输入流对象
            BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path));
            // 从缓存输入流中解码位图数据
            bitmap = BitmapFactory.decodeStream(bis);
            // 关闭缓存输入流
            bis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 返回图片文件中的位图数据
        return bitmap;
    }
 
    // 获得旋转角度之后的位图对象
    public static Bitmap getRotateBitmap(Bitmap b, float rotateDegree) {
        // 创建操作图片用的矩阵对象
        Matrix matrix = new Matrix();
        // 执行图片的旋转动作
        matrix.postRotate(rotateDegree);
        // 创建并返回旋转后的位图对象
        return Bitmap.createBitmap(b, 0, 0, b.getWidth(),
                b.getHeight(), matrix, false);
    }
 
    // 获得图片的缓存路径
    public static String getCachePath(Context context) {
        return context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() + "/";
    }
 
    // 按照新的宽高缩放位图对象
    public static Bitmap zoomImage(Bitmap origImage, double newWidth, double newHeight) {
        // 获取原始位图的宽度
        float width = origImage.getWidth();
        // 获取原始位图的高度
        float height = origImage.getHeight();
        // 创建操作图片用的矩阵对象
        Matrix matrix = new Matrix();
        // 计算宽度的缩放率
        float scaleWidth = ((float) newWidth) / width;
        // 计算高度的缩放率
        float scaleHeight = ((float) newHeight) / height;
        // 执行图片的缩放动作
        matrix.postScale(scaleWidth, scaleHeight);
        // 创建并返回缩放后的位图对象
        return Bitmap.createBitmap(origImage, 0, 0, (int) width, (int) height, matrix, true);
    }
 
    // 将图片的旋转角度置为0,此方法可以解决某些机型拍照后,图像出现了旋转情况
    public static void setPictureDegreeZero(String path) {
        try {
            ExifInterface exifInterface = new ExifInterface(path);
            // 修正图片的旋转角度,设置其不旋转。这里也可以设置其旋转的角度,可以传值过去,
            // 例如旋转90度,传值ExifInterface.ORIENTATION_ROTATE_90,需要将这个值转换为String类型的
            exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, "no");
            exifInterface.saveAttributes();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    private static ByteArrayOutputStream stream = new ByteArrayOutputStream();
    /**将nv21数据转换为Bitmap*/
    public static Bitmap nv21ToBitmap(byte[] nv21, int width, int height) {
        Bitmap bitmap = null;
        YuvImage image = new YuvImage(nv21, ImageFormat.NV21, width, height, null);
        //输出到对应流
        image.compressToJpeg(new Rect(0, 0, width, height), 100, stream);
        //对应字节流生成bitmap
        bitmap = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size());
        //避免中间的byte数组转换步骤,直接从YuvImage写入ByteBuffer,然后使用BitmapFactory的相应方法直接从ByteBuffer创建Bitmap
        stream.reset();
        return bitmap;
    }
 
    /**保存bitmap到文件*/
    public static void saveBitmapToFile(Bitmap bitmap) {
        // 定义图片的保存路径和文件名
        String fileName = "IMG_" + System.currentTimeMillis() + ".jpg";
        String filePath = Environment.getExternalStoragePublicDirectory(DIRECTORY_DOCUMENTS).getAbsolutePath()  + "/yc_test"+ File.separator + fileName;
        try(
            FileOutputStream fos = new FileOutputStream(filePath);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
        ){
            bitmap.compress(Bitmap.CompressFormat.JPEG, 99, bos);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            bitmap.recycle();
        }
    }
 
    /**
     * 避免中间的byte数组转换步骤,直接从YuvImage写入ByteBuffer,然后使用BitmapFactory的相应方法直接从ByteBuffer创建Bitmap
     * */
    /*public static Bitmap yuvToBitmap(Image image, int width, int height) {
        //获取YUV数据
        *//*int I420size = image.getWidth()*image.getHeight()*3/2;
        byte[] nv21 = new byte[I420size];
        Image.Plane[] planes = image.getPlanes();
        int remaining0 = planes[0].getBuffer().remaining();
        int remaining1 = planes[1].getBuffer().remaining();
        int remaining2 = planes[2].getBuffer().remaining();
        //分别准备三个数组接收YUV分量。
        byte[] yRawSrcBytes = new byte[remaining0];
        byte[] uRawSrcBytes = new byte[remaining1];
        byte[] vRawSrcBytes = new byte[remaining2];
        planes[0].getBuffer().get(yRawSrcBytes);
        planes[1].getBuffer().get(uRawSrcBytes);
        planes[2].getBuffer().get(vRawSrcBytes);*//*
 
        int W = image.getWidth();
        int H = image.getHeight();
 
        Image.Plane Y = image.getPlanes()[0];
        Image.Plane U = image.getPlanes()[1];
        Image.Plane V = image.getPlanes()[2];
 
        int Yb = Y.getBuffer().remaining();
        int Ub = U.getBuffer().remaining();
        int Vb = V.getBuffer().remaining();
 
        byte[] data = new byte[Yb + Ub + Vb];
 
 
        Y.getBuffer().get(data, 0, Yb);
        V.getBuffer().get(data, Yb, Vb);
        U.getBuffer().get(data, Yb + Vb, Ub);
 
 
 
        RenderScript rs = RenderScript.create(context);
        ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));
 
        Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)).setX(data.length);
        Allocation in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT);
 
        Type.Builder rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(W).setY(H);
        Allocation out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT);
 
        final Bitmap bmpout = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888);
 
        in.copyFromUnchecked(data);
 
        yuvToRgbIntrinsic.setInput(in);
        yuvToRgbIntrinsic.forEach(out);
        out.copyTo(bmpout);
        image.close();
        return bmpout ;
    }*/
}