Android 拍照 录音 拍视频 旋转 裁剪 压缩图片

Android 6.0 动态权限参考 https://blog.csdn.net/qq_27400335/article/details/79412774
Android 7.0 文件写入问题
在AndroidManifest.xml 配置 FileProvider
为了防止重复 android:authorities 一般配置为 包名.fileProvider
<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="包名.fileProvider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>
第二步

res添加 xml文件夹,添加file_paths.xml  写入:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <paths>
        <external-path
            name="camera_photos"
            path="" />
    </paths>
</resources>


//调用册并裁减
 //fileName 为全局变量(这里为了直观就没有写)
 String fileName = CameraUtils.photoAlbum(activity);
----------------------------------------------------------
//调用拍照并裁剪

String fileName = CameraUtils.photograph(activity);

------------------------------------------------------------------------------------

//调用拍视频

fileName = CameraUtils.shootVideo(activity);

--------------------------------------------------------------------------------------

//调用录音

CameraUtils.startRecord(new CameraUtils.RecordingCallBack() {
    @Override
    public void name(String name) {
        fileName = name;
    }

    @Override
    public void intent(Intent intent) {
        startActivityForResult(intent, CameraUtils.RECORD_FLAG);
    }
});

--------------------------------------------------------------------------------------------

//回调

//裁剪后的图片uri
private Uri cropUri;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode==-1){
        if (requestCode == CameraUtils.CAMERA_FLAG){
            //相机
            Uri uri= CameraUtils.compressCameraImg(mContext,fileName);
            if (uri!=null){
                //如不需要裁剪 可不走这一步
                cropUri=CameraUtils.crop(uri,this);
            }
        }else if (requestCode == CameraUtils.PHOTO_FLAG){
            //相册
            Uri uri = data.getData();
            if (uri!=null){
                //如不需要裁剪 可不走这一步
                cropUri=CameraUtils.crop(uri,this);
            }
        }else if (requestCode == CameraUtils.CROP_FLAG){
            //裁剪回调
            if (cropUri!=null){
                File file = null;
                try {
                    file = new File(new URI(cropUri.toString()));
                     .......           
                } catch (URISyntaxException e) {
                    e.printStackTrace();
                }
            }else {
                T.showShort(mContext,"裁剪失败");
            }
        }else if (requestCode == CameraUtils.VIDEO_FLAG){
               //视频回调 path 为视频地址
                String path = CameraUtils.PRESERVE_PATH+"/" + fileName;
                if (!TextUtils.isEmpty(fileName)){
                    //视频资料 
                    MediaMetadataRetriever media = new MediaMetadataRetriever();
                    media.setDataSource(path);

                    //获取时长 单位秒
                    String duration = media.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
                    //旋转角度
                    String rotation = media.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
                    ........
                }
       }else if (requestCode == CameraUtils.RECORD_FLAG) {
         //录音回调 uri 录音资源
           Uri uri = data.getData();
            String path = CameraUtils.PRESERVE_PATH+"/" + fileName;
           if (uri != null) {
                 String temp = CameraUtils.getAudioFilePathFromUri(uri, getActivity());
                 boolean b = CameraUtils.saveVoiceToSD(temp);
                 File file = new File(path);
                 if (b && file.exists()) {
                     //path  录音路径
                       ...
                   }
            }
    }
}

---------------------------------------------------------------------------------------------------------------------------------

//压缩图片(鲁班 Luban)

添加依赖:implementation 'top.zibin:Luban:1.1.3'
Luban.with(this)
        .load(stringList)// 传人要压缩的图片列表 也可单张 
        .ignoreBy(100)                                  // 忽略不压缩图片的大小
        .setTargetDir("")                        // 设置压缩后文件存储位置
        .setCompressListener(new OnCompressListener() { //设置回调
            @Override
            public void onStart() {
                
            }

            @Override
            public void onSuccess(File file) {
                // TODO 压缩成功后调用,返回压缩后的图片文件
               
            }

            @Override
            public void onError(Throwable e) {
                // TODO 当压缩过程出现问题时调用
               
            }
        }).launch();    //启动压缩

-----------------工具类----------------------
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.content.FileProvider;
import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

/**
 * Created by Administrator on 2019/3/12 0012.
 */

public class CameraUtils {

    //相机回调
    public static int CAMERA_FLAG = 1;
    //视频回调
    public static int VIDEO_FLAG = 2;
    //录音回调
    public static int RECORD_FLAG = 3;
    //裁剪回调
    public static int CROP_FLAG = 4;
    //相册回调
    public static int PHOTO_FLAG = 3;
    private static String fileName;
    private static String mVoicePath;

    //裁剪后图片保存路径
    private static final String IMAGE_FILE_LOCATION = "file:///sdcard/temp.jpg";
    //文件保存路劲
    private static final String PRESERVE_PATH = Environment.getExternalStorageDirectory() + "/宝宝印记";
    //provider
    private static final String FILE_PROVIDER_NAME = "包名.fileProvider";

    /**
     * 拍照
     * @param activity
     * @return
     */
    public static String photograph(Activity activity){
        fileName=null;
        UUID uuid = UUID.randomUUID();
        fileName = uuid + ".png";

        //将拍摄的照片保存在一个指定好的文件下
        File dir= new File(PRESERVE_PATH);
        if(!dir.exists()){
            dir.mkdirs();
        }
        File f = new File(dir, fileName);
        Uri u = Uri.fromFile(f);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            //通过FileProvider创建一个content类型的Uri
            u = FileProvider.getUriForFile(activity, FILE_PROVIDER_NAME, f);
        }

        //调用系统相机
        Intent intentCamera = new Intent();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            //添加这一句表示对目标应用临时授权该Uri所代表的文件
            intentCamera.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
        intentCamera.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
        //将拍照结果保存至photo_file的Uri中,不保留在相册中
        intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, u);
        activity.startActivityForResult(intentCamera, CAMERA_FLAG);
        return fileName;
    }


    /**
     * 相册
     * @param activity
     * @return
     */
    public static String photoAlbum(Activity activity){
        UUID uuid = UUID.randomUUID();
        fileName = uuid + ".png";

        Intent intent = new Intent(Intent.ACTION_PICK);
        //相片类型
        intent.setType("image/*");
        activity.startActivityForResult(intent, PHOTO_FLAG);
        return fileName;
    }


    /**
     * 裁剪
     * @param uri
     */
    public static Uri crop(Uri uri,Activity activity){
        Uri imageUri = Uri.parse(IMAGE_FILE_LOCATION);
        Intent intent = new Intent("com.android.camera.action.CROP");
        //图片资源uri
        intent.setDataAndType(uri, "image/*");

        intent.putExtra("crop", "true");

        intent.putExtra("aspectX", 1);

        intent.putExtra("aspectY", 1);

        intent.putExtra("outputX", 300);

        intent.putExtra("outputY", 300);

        intent.putExtra("scale", true);

        //截图返回的uri
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);

        intent.putExtra("return-data", false);

        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());

        intent.putExtra("noFaceDetection", true);
        activity.startActivityForResult(intent, CROP_FLAG);
        return imageUri;
    }

    /**
     * 视频
     * @param activity
     * @return
     */
    public static String shootVideo(Activity activity){
        fileName=null;
        UUID uuid = UUID.randomUUID();
        fileName = uuid + ".mp4";

        //将拍摄的照片保存在一个指定好的文件下
        File dir= new File(PRESERVE_PATH);
        if(!dir.exists()){
            dir.mkdirs();
        }
        File f = new File(dir, fileName);
        Uri u = Uri.fromFile(f);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            //通过FileProvider创建一个content类型的Uri
            u = FileProvider.getUriForFile(activity, FILE_PROVIDER_NAME, f);
        }

        //调用系统相机
        Intent intentVideo = new Intent();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            //添加这一句表示对目标应用临时授权该Uri所代表的文件
            intentVideo.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
        intentVideo.setAction(MediaStore.ACTION_VIDEO_CAPTURE);

        intentVideo.addCategory(Intent.CATEGORY_DEFAULT);

        //将拍照结果保存至photo_file的Uri中,不保留在相册中
        intentVideo.putExtra(MediaStore.EXTRA_OUTPUT, u);
        activity.startActivityForResult(intentVideo, VIDEO_FLAG);
        return fileName;
    }


    /**
     * 启动录音机,创建文件
     */
    public static void startRecord(RecordingCallBack callBack) {

        UUID uuid = UUID.randomUUID();
        fileName = uuid + ".amr";

        //将拍摄的照片保存在一个指定好的文件下
        File dir= new File(PRESERVE_PATH);
        if(!dir.exists()){
            dir.mkdirs();
        }

        callBack.name(fileName);

        File f = new File(dir, fileName);

        mVoicePath = f.getAbsolutePath();

        f.setWritable(true);

        Intent intentRecord = new Intent();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            //添加这一句表示对目标应用临时授权该Uri所代表的文件
            intentRecord.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }

        intentRecord.setAction(MediaStore.Audio.Media.RECORD_SOUND_ACTION);

        callBack.intent(intentRecord);
    }


    /**
     * 通过Uri,获取录音文件的路径(绝对路径)
     *
     * @param uri 录音文件的uri
     * @return 录音文件的路径(String)
     */
    public static String getAudioFilePathFromUri(Uri uri,Activity activity) {
        Cursor cursor = activity.getContentResolver()
                .query(uri, null, null, null, null);
        cursor.moveToFirst();
        int index = cursor.getColumnIndex(MediaStore.Audio.AudioColumns.DATA);
        String temp = cursor.getString(index);
        cursor.close();
        return temp;
    }

    /**
     * 保存音频到SD卡的指定位置
     *
     * @param path 录音文件的路径
     */
    public static boolean saveVoiceToSD(String path) {
        boolean b = false;
        //创建输入输出
        InputStream isFrom = null;
        OutputStream osTo = null;
        try {
            //设置输入输出流
            isFrom = new FileInputStream(path);
            osTo = new FileOutputStream(mVoicePath);
            byte bt[] = new byte[1024];
            int len;
            while ((len = isFrom.read(bt)) != -1) {
                osTo.write(bt, 0, len);
            }
            Log.d("TAG_Path", "保存录音完成。");
            b=true;
        } catch (IOException e) {
            e.printStackTrace();
            b=false;
            Log.d("TAG_Path", "e:"+e.toString());
        } finally {
            if (osTo != null) {
                try {
                    //不管是否出现异常,都要关闭流
                    osTo.close();
                    Log.d("TAG_Path", "关闭输出流");
                } catch (IOException e) {
                    e.printStackTrace();
                    b=false;
                }
            }
            if (isFrom != null) {
                try {
                    isFrom.close();
                    Log.d("TAG_Path", "关闭输入流");
                } catch (IOException e) {
                    e.printStackTrace();
                    b=false;
                }
            }
        }

        return b;
    }

    public interface RecordingCallBack{
        void name(String name);
        void intent(Intent intent);
    }

    public static Uri compressCameraImg(Context mContext,String fileName){
        Uri imgUrl=null;
        if (fileName==null){
            return null;
        }
        //返回原图
        File fData = new File(PRESERVE_PATH+"/" + fileName);
        try {
            imgUrl = Uri.parse(MediaStore.Images.Media.insertImage(mContext.getContentResolver(), fData.getAbsolutePath(), null, null));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return imgUrl;
    }


    /**
     * android 转换 content://media/external/images/media/xxx
     * @param context
     * @param contentUri
     * @return
     */
    public static String getRealPathFromUri(Context context, Uri contentUri) {
        Cursor cursor = null;
        try {
            String[] proj = { MediaStore.Images.Media.DATA };
            cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }

/**
 * 获取图片旋转角度
 * 注意:获取图片旋转角度之前不能做任何操作(如:压缩、裁剪)
 * 注意:在高版本中 ExifInterface 会抛异常
 * 解决方法:添加ExifInterface的依赖 implementation "com.android.support:exifinterface:27.1.1"(对应自己的SDK版本)
 * @param path  图片路径
 * @return  图片旋转角度
 */
public static int readPictureDegree(String path) {
    int degree = 0;
    try {
        ExifInterface exifInterface = new ExifInterface(path);
        int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
        switch (orientation) {
            case ExifInterface.ORIENTATION_ROTATE_90:
                degree = 90;
                break;
            case ExifInterface.ORIENTATION_ROTATE_180:
                degree = 180;
                break;
            case ExifInterface.ORIENTATION_ROTATE_270:
                degree = 270;
                break;
            default:
                break;
        }
    } catch (IOException e) {
        e.printStackTrace();
        return degree;
    }
    return degree;
}


/**
 * 旋转图片
 * @param degree 旋转角度
 * @param bitmap 旋转图片
 * @return
 */
public static Bitmap rotaingImageView(int degree, Bitmap bitmap) {
    Matrix matrix = new Matrix();
    matrix.postRotate(degree);
    Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
            bitmap.getWidth(), bitmap.getHeight(), matrix, true);
    return resizedBitmap;
}

/**
 * 旋转图片并保存到本地
 * @param degree 旋转角度
 * @param bitmap 旋转图片
 * @return 返回图片路径
 */
public static String rotaingImageViewAndSave(Activity activity,int degree, Bitmap bitmap) {
    String path = null;
    Matrix matrix = new Matrix();
    matrix.postRotate(degree);

    //设置图片缩放比例 长和宽放大缩小的比例
    //matrix.postScale(0.5f,0.5f);

    Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
            bitmap.getWidth(), bitmap.getHeight(), matrix, true);


    if (resizedBitmap!=null){
        //保存照片
        path = saveBitmap(activity,resizedBitmap,"");
    }
    return path;
}

/**
 * 保存文件到相册,文件名为当前日期
 * @param activity
 * @param bitmap  图片资源
 * @param imageName  图片名称
 * @return  返回图片路径
 */
public static String saveBitmap(Activity activity,Bitmap bitmap, String imageName){
    String fileName ;
    File file =null;
    if(Build.BRAND .equals("Xiaomi") ){
        fileName = Environment.getExternalStorageDirectory().getPath()+"/DCIM/Camera/"+imageName ;
    }else{
        fileName = Environment.getExternalStorageDirectory().getPath()+"/DCIM/"+imageName ;
    }
    file = new File(fileName);

    if(file.exists()){
        file.delete();
    }
    FileOutputStream out;
    try{
        out = new FileOutputStream(file);
        // 格式为 JPEG,照相机拍出的图片为JPEG格式的,PNG格式的不能显示在相册中
        if(bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out)){
            out.flush();
            out.close();
            // 插入图库
            MediaStore.Images.Media.insertImage(activity.getContentResolver(), file.getAbsolutePath(), imageName, null);

        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    // 发送广播,通知刷新图库的显示
    activity.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + fileName)));

    if (file != null){
        return file.getPath();
    }else {
        return "";
    }
}
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现拍照裁剪图片功能需要以下步骤: 1. 添加权限 在AndroidManifest.xml文件中添加以下权限: ```xml <uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> ``` 2. 创建布局文件 创建一个布局文件camera_preview.xml,并添加一个SurfaceView和一个Button,用于显示和拍照。 ```xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/camera_preview" android:layout_width="match_parent" android:layout_height="match_parent"> <SurfaceView android:id="@+id/surface_view" android:layout_width="match_parent" android:layout_height="match_parent"/> <Button android:id="@+id/button_capture" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="拍照" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true"/> </RelativeLayout> ``` 3. 实现拍照功能 在Activity中,获取Camera实例,并在SurfaceView上显示预览图像。当用户点击拍照按钮时,调用Camera.takePicture()方法拍照拍照成功后,保存照片并显示裁剪界面。 ```java public class CameraActivity extends Activity implements SurfaceHolder.Callback { private Camera mCamera; private SurfaceView mSurfaceView; private SurfaceHolder mSurfaceHolder; private Button mButtonCapture; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.camera_preview); // 获取SurfaceView和Button实例 mSurfaceView = findViewById(R.id.surface_view); mButtonCapture = findViewById(R.id.button_capture); // 监听Button点击事件 mButtonCapture.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 拍照 mCamera.takePicture(null, null, mPictureCallback); } }); // 获取SurfaceHolder实例,并添加回调监听 mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.addCallback(this); } @Override public void surfaceCreated(SurfaceHolder holder) { // 打开摄像头并设置预览 mCamera = Camera.open(); try { mCamera.setPreviewDisplay(holder); mCamera.startPreview(); } catch (IOException e) { Log.d("CameraTest", "Error setting camera preview: " + e.getMessage()); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // 在SurfaceView上显示预览图像 if (mSurfaceHolder.getSurface() == null) { return; } try { mCamera.stopPreview(); } catch (Exception e) { Log.d("CameraTest", "Error stopping camera preview: " + e.getMessage()); } try { mCamera.setPreviewDisplay(mSurfaceHolder); mCamera.startPreview(); } catch (Exception e) { Log.d("CameraTest", "Error starting camera preview: " + e.getMessage()); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { // 释放摄像头资源 mCamera.stopPreview(); mCamera.release(); mCamera = null; } private Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { // 保存照片 File pictureFile = getOutputMediaFile(); if (pictureFile == null) { Log.d("CameraTest", "Error creating media file, check storage permissions"); return; } try { FileOutputStream fos = new FileOutputStream(pictureFile); fos.write(data); fos.close(); } catch (FileNotFoundException e) { Log.d("CameraTest", "File not found: " + e.getMessage()); } catch (IOException e) { Log.d("CameraTest", "Error accessing file: " + e.getMessage()); } // 显示裁剪界面 Intent intent = new Intent(CameraActivity.this, CropActivity.class); intent.putExtra("image_path", pictureFile.getPath()); startActivity(intent); } }; private File getOutputMediaFile() { // 创建目录 File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), "MyCameraApp"); if (!mediaStorageDir.exists()) { if (!mediaStorageDir.mkdirs()) { Log.d("CameraTest", "failed to create directory"); return null; } } // 创建文件 String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); File mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg"); return mediaFile; } } ``` 4. 实现裁剪功能 创建一个布局文件crop.xml,添加一个ImageView和一个Button,用于显示图片和保存裁剪后的图片。 ```xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/crop_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/image_view" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitCenter"/> <Button android:id="@+id/button_save" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="保存" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true"/> </RelativeLayout> ``` 在CropActivity中,获取传递过来的图片路径,并将图片显示在ImageView上。当用户点击保存按钮时,调用Bitmap.createBitmap()方法裁剪图片,并保存到相册。 ```java public class CropActivity extends Activity { private ImageView mImageView; private Button mButtonSave; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.crop); // 获取ImageView和Button实例 mImageView = findViewById(R.id.image_view); mButtonSave = findViewById(R.id.button_save); // 获取传递过来的图片路径 Intent intent = getIntent(); String imagePath = intent.getStringExtra("image_path"); // 将图片显示在ImageView上 Bitmap bitmap = BitmapFactory.decodeFile(imagePath); mImageView.setImageBitmap(bitmap); // 监听Button点击事件 mButtonSave.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 裁剪并保存图片 Bitmap croppedBitmap = getCroppedBitmap(bitmap); saveBitmapToGallery(croppedBitmap); Toast.makeText(getApplicationContext(), "保存成功", Toast.LENGTH_SHORT).show(); finish(); } }); } private Bitmap getCroppedBitmap(Bitmap bitmap) { // 获取ImageView的尺寸 int viewWidth = mImageView.getWidth(); int viewHeight = mImageView.getHeight(); // 获取图片的尺寸 int imageWidth = bitmap.getWidth(); int imageHeight = bitmap.getHeight(); // 计算缩放比例 float scale = Math.min((float) viewWidth / imageWidth, (float) viewHeight / imageHeight); // 计算裁剪区域 int cropWidth = (int) (viewWidth / scale); int cropHeight = (int) (viewHeight / scale); int x = (imageWidth - cropWidth) / 2; int y = (imageHeight - cropHeight) / 2; // 裁剪图片 Bitmap croppedBitmap = Bitmap.createBitmap(bitmap, x, y, cropWidth, cropHeight); return croppedBitmap; } private void saveBitmapToGallery(Bitmap bitmap) { // 创建目录 File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), "MyCameraApp"); if (!mediaStorageDir.exists()) { if (!mediaStorageDir.mkdirs()) { Log.d("CameraTest", "failed to create directory"); return; } } // 保存图片 String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String imagePath = mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg"; File imageFile = new File(imagePath); try { FileOutputStream fos = new FileOutputStream(imageFile); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); fos.flush(); fos.close(); } catch (IOException e) { Log.d("CameraTest", "Error accessing file: " + e.getMessage()); } // 通知相册更新 MediaScannerConnection.scanFile(this, new String[]{imagePath}, null, null); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值