保存图片到相册

直接调用系统方法MediaStore类实现

  • 需要图片路径和名称

        /**
         * Insert an image and create a thumbnail for it.
         *
         * @param cr The content resolver to use
         * @param imagePath The path to the image to insert
         * @param name The name of the image
         * @param description The description of the image
         * @return The URL to the newly created image
         * @throws FileNotFoundException
         */
        public static final String insertImage(ContentResolver cr, String imagePath,
                String name, String description) throws FileNotFoundException {
            // Check if file exists with a FileInputStream
            FileInputStream stream = new FileInputStream(imagePath);
            try {
                Bitmap bm = BitmapFactory.decodeFile(imagePath);
                String ret = insertImage(cr, bm, name, description);
                bm.recycle();
                return ret;
            } finally {
                try {
                    stream.close();
                } catch (IOException e) {
                }
            }
        }
    
  • 需要图片bitmap值和图片名称

        /**
         * Insert an image and create a thumbnail for it.
         *
         * @param cr The content resolver to use
         * @param source The stream to use for the image
         * @param title The name of the image
         * @param description The description of the image
         * @return The URL to the newly created image, or <code>null</code> if the image failed to be stored
         *              for any reason.
         */
        public static final String insertImage(ContentResolver cr, Bitmap source,
                                               String title, String description) {
            ContentValues values = new ContentValues();
            values.put(Images.Media.TITLE, title);
            values.put(Images.Media.DESCRIPTION, description);
            values.put(Images.Media.MIME_TYPE, "image/jpeg");
    
            Uri url = null;
            String stringUrl = null;    /* value to be returned */
    
            try {
                url = cr.insert(EXTERNAL_CONTENT_URI, values);
    
                if (source != null) {
                    OutputStream imageOut = cr.openOutputStream(url);
                    try {
                        source.compress(Bitmap.CompressFormat.JPEG, 50, imageOut);
                    } finally {
                        imageOut.close();
                    }
    
                    long id = ContentUris.parseId(url);
                    // Wait until MINI_KIND thumbnail is generated.
                    Bitmap miniThumb = Images.Thumbnails.getThumbnail(cr, id,
                            Images.Thumbnails.MINI_KIND, null);
                    // This is for backward compatibility.
                    Bitmap microThumb = StoreThumbnail(cr, miniThumb, id, 50F, 50F,
                            Images.Thumbnails.MICRO_KIND);
                } else {
                    Log.e(TAG, "Failed to create thumbnail, removing original");
                    cr.delete(url, null, null);
                    url = null;
                }
            } catch (Exception e) {
                Log.e(TAG, "Failed to insert image", e);
                if (url != null) {
                    cr.delete(url, null, null);
                    url = null;
                }
            }
    
            if (url != null) {
                stringUrl = url.toString();
            }
    
            return stringUrl;
        }
    

上面两种方式理论上都是可行的,但是有一个问题,就是这两种方式在真正执行插入动作时,需要把固定路径下的图片首先转为bitmap,然后给到ContentResolver的OutputStream。 这样导致的问题就是。如果是小图片没问题,但是如果是比较大的图,在图片转bitmap过程中会非常大概率出现OOM.

    Bitmap bm = BitmapFactory.decodeFile(imagePath);

换个思路,如果通过文件流方式写入ContentResolver的OutputStream,转Bitmap过程的OOM应该会解决

改写系统方法

/**
  * 保存图片到相册
  *
  * @param filePath The path to the image to insert
  * @param name The name of the image
  * @return 图片是否成功插入到相册
  * @throws FileNotFoundException
  */
public static boolean saveImage2Gallery(Context context, String filePath, String fileName) throws IOException {
    if (context == null || fileName == null || filePath == null) {
        Log.e(TAG, "saveImage2Gallery: context: " + context + ",filePath: " + filePath + ",fileName: " + fileName);
        return false;
    }
    File file = new File(filePath, fileName);
    if (!file.exists()) {
        throw new FileNotFoundException();
    }

    if (isPicMedia(fileName)) {
        ContentResolver contentResolver = context.getContentResolver();
        //向多媒体数据库中插入一条记录
        ContentValues values = new ContentValues(3);
        values.put(MediaStore.Images.Media.TITLE, "");
        values.put(MediaStore.Images.Media.DESCRIPTION, "");
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        Uri url = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        //查询新创建记录的id
        if (url != null) {
            long id = ContentUris.parseId(url);
            OutputStream outputStream = null;
            FileInputStream fileInputStream = null;
            try {
                outputStream = contentResolver.openOutputStream(url);
                //向uri中写图片数据
                fileInputStream = new FileInputStream(new File(filePath, fileName));
                byte[] buffer = new byte[1024 * 5];
                int len;
                while ((len = fileInputStream.read(buffer)) != -1) {
                    if (outputStream != null) {
                        outputStream.write(buffer, 0, len);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                throw new IOException();
            } finally {
                try {
                    if (outputStream != null) {
                        outputStream.close();
                    }
                    if (fileInputStream != null) {
                        fileInputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            //生成缩略图
            Bitmap miniThumb = MediaStore.Images.Thumbnails.getThumbnail(contentResolver, id,
                    MediaStore.Images.Thumbnails.MINI_KIND, null);
            //将缩略图插入到数据库(MediaStore类内部private方法,可copy出来)
            Bitmap microThumb = StoreThumbnail(contentResolver, miniThumb, id, 50F, 50F,
                    MediaStore.Images.Thumbnails.MICRO_KIND);
            //插入相册成功后把原路径图片删除
            FileUtil.deleteFile(new File(filePath, fileName));
            String realPath = getFilePathFromContentUri(url, contentResolver);
            if(!TextUtils.isEmpty(realPath)) {
                //通知系统更新此文件
                Timber.i("插入相册后的路径------>"+realPath);
                File insertFile = new File(realPath);
                notifyMediaFileScan(context, insertFile.getParent(), insertFile.getName());
            }
            return true;
        }
        return false;
    } else {
        Log.e(TAG, "saveImage2Gallery: file type error. fileName : " + fileName);
        return false;
    }
}
/**
 * Gets the corresponding path to a file from the given content:// URI
 * @param selectedVideoUri The content:// URI to find the file path from
 * @param contentResolver The content resolver to use to perform the query.
 * @return the file path as a string
 */
public static String getFilePathFromContentUri(Uri selectedVideoUri,
                                               ContentResolver contentResolver) {
    String filePath;
    String[] filePathColumn = {MediaStore.MediaColumns.DATA};

    Cursor cursor = contentResolver.query(selectedVideoUri, filePathColumn, null, null, null);
    //也可用下面的方法拿到cursor
    //Cursor cursor = this.context.managedQuery(selectedVideoUri, filePathColumn, null, null, null);

    cursor.moveToFirst();

    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
    filePath = cursor.getString(columnIndex);
    cursor.close();
    return filePath;
}
//通知系统文件改动
public static void notifyMediaFileScan(Context context, String path, String fileName) {
    context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File(path, fileName))));
}

附网上说的比较多的通知图库刷新方法

// 通知图库更新(路径)
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + path)));

context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File("/sdcard/Boohee/image.jpg"))););

不加载图片的前提下获得图片的宽高(防止为得到图片宽高而加载到内存的浪费)

   BitmapFactory.Options options = new BitmapFactory.Options();  

   /** 
    * 最关键在此,把options.inJustDecodeBounds = true; 
    * 这里再decodeFile(),返回的bitmap为空,但此时调用options.outHeight时,已经包含了图片的高了 
    */  
   options.inJustDecodeBounds = true;  
   Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/test.jpg", options); // 此时返回的bitmap为null  
   /** 
    *options.outHeight为原始图片的高 
    */  
   Log.e("Test", "Bitmap Height == " + options.outHeight);  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值