Android图片压缩(质量压缩和尺寸压缩)&Bitmap转成字符串上传

Android图片压缩(质量压缩和尺寸压缩)&Bitmap转成字符串上传

53665人阅读 评论(34) 收藏 举报
本文章已收录于:
category_icon.jpg 分类:
在网上调查了图片压缩的方法并实装后,大致上可以认为有两类压缩:质量压缩(不改变图片的尺寸)和尺寸压缩(相当于是像素上的压缩);质量压缩一般可用于上传大图前的处理,这样就可以节省一定的流量,毕竟现在的手机拍照都能达到3M左右了,尺寸压缩一般可用于生成缩略图。
两种方法都实装在了我的项目中,结果却发现在质量压缩的模块中,本来1.9M的图片压缩后反而变成3M多了,很是奇怪,再做了进一步调查终于知道原因了。下面这个博客说的比较清晰:

android图片压缩总结

总结来看,图片有三种存在形式:硬盘上时是file,网络传输时是stream,内存中是stream或bitmap,所谓的质量压缩,它其实只能实现对file的影响,你可以把一个file转成bitmap再转成file,或者直接将一个bitmap转成file时,这个最终的file是被压缩过的,但是中间的bitmap并没有被压缩(或者说几乎没有被压缩,我不确定),因为bigmap在内存中的大小是按像素计算的,也就是width * height,对于质量压缩,并不会改变图片的像素,所以就算质量被压缩了,但是bitmap在内存的占有率还是没变小,但你做成file时,它确实变小了;

而尺寸压缩由于是减小了图片的像素,所以它直接对bitmap产生了影响,当然最终的file也是相对的变小了;

最后把自己总结的工具类贴出来:
  1. import java.io.ByteArrayInputStream;  
  2. import java.io.ByteArrayOutputStream;  
  3. import java.io.File;  
  4. import java.io.FileNotFoundException;  
  5. import java.io.FileOutputStream;  
  6. import java.io.IOException;  
  7.   
  8. import android.graphics.Bitmap;  
  9. import android.graphics.Bitmap.Config;  
  10. import android.graphics.BitmapFactory;  
  11.   
  12. /** 
  13.  * Image compress factory class 
  14.  *  
  15.  * @author  
  16.  * 
  17.  */  
  18. public class ImageFactory {  
  19.   
  20.     /** 
  21.      * Get bitmap from specified image path 
  22.      *  
  23.      * @param imgPath 
  24.      * @return 
  25.      */  
  26.     public Bitmap getBitmap(String imgPath) {  
  27.         // Get bitmap through image path  
  28.         BitmapFactory.Options newOpts = new BitmapFactory.Options();  
  29.         newOpts.inJustDecodeBounds = false;  
  30.         newOpts.inPurgeable = true;  
  31.         newOpts.inInputShareable = true;  
  32.         // Do not compress  
  33.         newOpts.inSampleSize = 1;  
  34.         newOpts.inPreferredConfig = Config.RGB_565;  
  35.         return BitmapFactory.decodeFile(imgPath, newOpts);  
  36.     }  
  37.       
  38.     /** 
  39.      * Store bitmap into specified image path 
  40.      *  
  41.      * @param bitmap 
  42.      * @param outPath 
  43.      * @throws FileNotFoundException  
  44.      */  
  45.     public void storeImage(Bitmap bitmap, String outPath) throws FileNotFoundException {  
  46.         FileOutputStream os = new FileOutputStream(outPath);  
  47.         bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);  
  48.     }  
  49.       
  50.     /** 
  51.      * Compress image by pixel, this will modify image width/height.  
  52.      * Used to get thumbnail 
  53.      *  
  54.      * @param imgPath image path 
  55.      * @param pixelW target pixel of width 
  56.      * @param pixelH target pixel of height 
  57.      * @return 
  58.      */  
  59.     public Bitmap ratio(String imgPath, float pixelW, float pixelH) {  
  60.         BitmapFactory.Options newOpts = new BitmapFactory.Options();    
  61.         // 开始读入图片,此时把options.inJustDecodeBounds 设回true,即只读边不读内容  
  62.         newOpts.inJustDecodeBounds = true;  
  63.         newOpts.inPreferredConfig = Config.RGB_565;  
  64.         // Get bitmap info, but notice that bitmap is null now    
  65.         Bitmap bitmap = BitmapFactory.decodeFile(imgPath,newOpts);  
  66.             
  67.         newOpts.inJustDecodeBounds = false;    
  68.         int w = newOpts.outWidth;    
  69.         int h = newOpts.outHeight;    
  70.         // 想要缩放的目标尺寸  
  71.         float hh = pixelH;// 设置高度为240f时,可以明显看到图片缩小了  
  72.         float ww = pixelW;// 设置宽度为120f,可以明显看到图片缩小了  
  73.         // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可    
  74.         int be = 1;//be=1表示不缩放    
  75.         if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放    
  76.             be = (int) (newOpts.outWidth / ww);    
  77.         } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放    
  78.             be = (int) (newOpts.outHeight / hh);    
  79.         }    
  80.         if (be <= 0) be = 1;    
  81.         newOpts.inSampleSize = be;//设置缩放比例  
  82.         // 开始压缩图片,注意此时已经把options.inJustDecodeBounds 设回false了  
  83.         bitmap = BitmapFactory.decodeFile(imgPath, newOpts);  
  84.         // 压缩好比例大小后再进行质量压缩  
  85. //        return compress(bitmap, maxSize); // 这里再进行质量压缩的意义不大,反而耗资源,删除  
  86.         return bitmap;  
  87.     }  
  88.       
  89.     /** 
  90.      * Compress image by size, this will modify image width/height.  
  91.      * Used to get thumbnail 
  92.      *  
  93.      * @param image 
  94.      * @param pixelW target pixel of width 
  95.      * @param pixelH target pixel of height 
  96.      * @return 
  97.      */  
  98.     public Bitmap ratio(Bitmap image, float pixelW, float pixelH) {  
  99.         ByteArrayOutputStream os = new ByteArrayOutputStream();  
  100.         image.compress(Bitmap.CompressFormat.JPEG, 100, os);  
  101.         if( os.toByteArray().length / 1024>1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出      
  102.             os.reset();//重置baos即清空baos    
  103.             image.compress(Bitmap.CompressFormat.JPEG, 50, os);//这里压缩50%,把压缩后的数据存放到baos中    
  104.         }    
  105.         ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());    
  106.         BitmapFactory.Options newOpts = new BitmapFactory.Options();    
  107.         //开始读入图片,此时把options.inJustDecodeBounds 设回true了    
  108.         newOpts.inJustDecodeBounds = true;  
  109.         newOpts.inPreferredConfig = Config.RGB_565;  
  110.         Bitmap bitmap = BitmapFactory.decodeStream(is, null, newOpts);    
  111.         newOpts.inJustDecodeBounds = false;    
  112.         int w = newOpts.outWidth;    
  113.         int h = newOpts.outHeight;    
  114.         float hh = pixelH;// 设置高度为240f时,可以明显看到图片缩小了  
  115.         float ww = pixelW;// 设置宽度为120f,可以明显看到图片缩小了  
  116.         //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可    
  117.         int be = 1;//be=1表示不缩放    
  118.         if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放    
  119.             be = (int) (newOpts.outWidth / ww);    
  120.         } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放    
  121.             be = (int) (newOpts.outHeight / hh);    
  122.         }    
  123.         if (be <= 0) be = 1;    
  124.         newOpts.inSampleSize = be;//设置缩放比例    
  125.         //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了    
  126.         is = new ByteArrayInputStream(os.toByteArray());    
  127.         bitmap = BitmapFactory.decodeStream(is, null, newOpts);  
  128.         //压缩好比例大小后再进行质量压缩  
  129. //      return compress(bitmap, maxSize); // 这里再进行质量压缩的意义不大,反而耗资源,删除  
  130.         return bitmap;  
  131.     }  
  132.       
  133.     /** 
  134.      * Compress by quality,  and generate image to the path specified 
  135.      *  
  136.      * @param image 
  137.      * @param outPath 
  138.      * @param maxSize target will be compressed to be smaller than this size.(kb) 
  139.      * @throws IOException  
  140.      */  
  141.     public void compressAndGenImage(Bitmap image, String outPath, int maxSize) throws IOException {  
  142.         ByteArrayOutputStream os = new ByteArrayOutputStream();  
  143.         // scale  
  144.         int options = 100;  
  145.         // Store the bitmap into output stream(no compress)  
  146.         image.compress(Bitmap.CompressFormat.JPEG, options, os);    
  147.         // Compress by loop  
  148.         while ( os.toByteArray().length / 1024 > maxSize) {  
  149.             // Clean up os  
  150.             os.reset();  
  151.             // interval 10  
  152.             options -= 10;  
  153.             image.compress(Bitmap.CompressFormat.JPEG, options, os);  
  154.         }  
  155.           
  156.         // Generate compressed image file  
  157.         FileOutputStream fos = new FileOutputStream(outPath);    
  158.         fos.write(os.toByteArray());    
  159.         fos.flush();    
  160.         fos.close();    
  161.     }  
  162.       
  163.     /** 
  164.      * Compress by quality,  and generate image to the path specified 
  165.      *  
  166.      * @param imgPath 
  167.      * @param outPath 
  168.      * @param maxSize target will be compressed to be smaller than this size.(kb) 
  169.      * @param needsDelete Whether delete original file after compress 
  170.      * @throws IOException  
  171.      */  
  172.     public void compressAndGenImage(String imgPath, String outPath, int maxSize, boolean needsDelete) throws IOException {  
  173.         compressAndGenImage(getBitmap(imgPath), outPath, maxSize);  
  174.           
  175.         // Delete original file  
  176.         if (needsDelete) {  
  177.             File file = new File (imgPath);  
  178.             if (file.exists()) {  
  179.                 file.delete();  
  180.             }  
  181.         }  
  182.     }  
  183.       
  184.     /** 
  185.      * Ratio and generate thumb to the path specified 
  186.      *  
  187.      * @param image 
  188.      * @param outPath 
  189.      * @param pixelW target pixel of width 
  190.      * @param pixelH target pixel of height 
  191.      * @throws FileNotFoundException 
  192.      */  
  193.     public void ratioAndGenThumb(Bitmap image, String outPath, float pixelW, float pixelH) throws FileNotFoundException {  
  194.         Bitmap bitmap = ratio(image, pixelW, pixelH);  
  195.         storeImage( bitmap, outPath);  
  196.     }  
  197.       
  198.     /** 
  199.      * Ratio and generate thumb to the path specified 
  200.      *  
  201.      * @param image 
  202.      * @param outPath 
  203.      * @param pixelW target pixel of width 
  204.      * @param pixelH target pixel of height 
  205.      * @param needsDelete Whether delete original file after compress 
  206.      * @throws FileNotFoundException 
  207.      */  
  208.     public void ratioAndGenThumb(String imgPath, String outPath, float pixelW, float pixelH, boolean needsDelete) throws FileNotFoundException {  
  209.         Bitmap bitmap = ratio(imgPath, pixelW, pixelH);  
  210.         storeImage( bitmap, outPath);  
  211.           
  212.         // Delete original file  
  213.                 if (needsDelete) {  
  214.                     File file = new File (imgPath);  
  215.                     if (file.exists()) {  
  216.                         file.delete();  
  217.                     }  
  218.                 }  
  219.     }  
  220.       
  221. }  
save_snippets.png
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;

/**
 * Image compress factory class
 * 
 * @author 
 *
 */
public class ImageFactory {

	/**
	 * Get bitmap from specified image path
	 * 
	 * @param imgPath
	 * @return
	 */
	public Bitmap getBitmap(String imgPath) {
		// Get bitmap through image path
		BitmapFactory.Options newOpts = new BitmapFactory.Options();
		newOpts.inJustDecodeBounds = false;
		newOpts.inPurgeable = true;
		newOpts.inInputShareable = true;
		// Do not compress
		newOpts.inSampleSize = 1;
		newOpts.inPreferredConfig = Config.RGB_565;
		return BitmapFactory.decodeFile(imgPath, newOpts);
	}
	
	/**
	 * Store bitmap into specified image path
	 * 
	 * @param bitmap
	 * @param outPath
	 * @throws FileNotFoundException 
	 */
	public void storeImage(Bitmap bitmap, String outPath) throws FileNotFoundException {
		FileOutputStream os = new FileOutputStream(outPath);
		bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
	}
	
	/**
	 * Compress image by pixel, this will modify image width/height. 
	 * Used to get thumbnail
	 * 
	 * @param imgPath image path
	 * @param pixelW target pixel of width
	 * @param pixelH target pixel of height
	 * @return
	 */
	public Bitmap ratio(String imgPath, float pixelW, float pixelH) {
		BitmapFactory.Options newOpts = new BitmapFactory.Options();  
        // 开始读入图片,此时把options.inJustDecodeBounds 设回true,即只读边不读内容
        newOpts.inJustDecodeBounds = true;
        newOpts.inPreferredConfig = Config.RGB_565;
        // Get bitmap info, but notice that bitmap is null now  
        Bitmap bitmap = BitmapFactory.decodeFile(imgPath,newOpts);
          
        newOpts.inJustDecodeBounds = false;  
        int w = newOpts.outWidth;  
        int h = newOpts.outHeight;  
        // 想要缩放的目标尺寸
        float hh = pixelH;// 设置高度为240f时,可以明显看到图片缩小了
	    float ww = pixelW;// 设置宽度为120f,可以明显看到图片缩小了
        // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可  
        int be = 1;//be=1表示不缩放  
        if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放  
            be = (int) (newOpts.outWidth / ww);  
        } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放  
            be = (int) (newOpts.outHeight / hh);  
        }  
        if (be <= 0) be = 1;  
        newOpts.inSampleSize = be;//设置缩放比例
        // 开始压缩图片,注意此时已经把options.inJustDecodeBounds 设回false了
        bitmap = BitmapFactory.decodeFile(imgPath, newOpts);
        // 压缩好比例大小后再进行质量压缩
//        return compress(bitmap, maxSize); // 这里再进行质量压缩的意义不大,反而耗资源,删除
        return bitmap;
	}
	
	/**
	 * Compress image by size, this will modify image width/height. 
	 * Used to get thumbnail
	 * 
	 * @param image
	 * @param pixelW target pixel of width
	 * @param pixelH target pixel of height
	 * @return
	 */
	public Bitmap ratio(Bitmap image, float pixelW, float pixelH) {
		ByteArrayOutputStream os = new ByteArrayOutputStream();
	    image.compress(Bitmap.CompressFormat.JPEG, 100, os);
	    if( os.toByteArray().length / 1024>1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出    
	        os.reset();//重置baos即清空baos  
	        image.compress(Bitmap.CompressFormat.JPEG, 50, os);//这里压缩50%,把压缩后的数据存放到baos中  
	    }  
	    ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());  
	    BitmapFactory.Options newOpts = new BitmapFactory.Options();  
	    //开始读入图片,此时把options.inJustDecodeBounds 设回true了  
	    newOpts.inJustDecodeBounds = true;
	    newOpts.inPreferredConfig = Config.RGB_565;
	    Bitmap bitmap = BitmapFactory.decodeStream(is, null, newOpts);  
	    newOpts.inJustDecodeBounds = false;  
	    int w = newOpts.outWidth;  
	    int h = newOpts.outHeight;  
	    float hh = pixelH;// 设置高度为240f时,可以明显看到图片缩小了
	    float ww = pixelW;// 设置宽度为120f,可以明显看到图片缩小了
	    //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可  
	    int be = 1;//be=1表示不缩放  
	    if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放  
	        be = (int) (newOpts.outWidth / ww);  
	    } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放  
	        be = (int) (newOpts.outHeight / hh);  
	    }  
	    if (be <= 0) be = 1;  
	    newOpts.inSampleSize = be;//设置缩放比例  
	    //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了  
	    is = new ByteArrayInputStream(os.toByteArray());  
	    bitmap = BitmapFactory.decodeStream(is, null, newOpts);
	    //压缩好比例大小后再进行质量压缩
//	    return compress(bitmap, maxSize); // 这里再进行质量压缩的意义不大,反而耗资源,删除
	    return bitmap;
	}
	
	/**
	 * Compress by quality,  and generate image to the path specified
	 * 
	 * @param image
	 * @param outPath
	 * @param maxSize target will be compressed to be smaller than this size.(kb)
	 * @throws IOException 
	 */
	public void compressAndGenImage(Bitmap image, String outPath, int maxSize) throws IOException {
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		// scale
		int options = 100;
		// Store the bitmap into output stream(no compress)
        image.compress(Bitmap.CompressFormat.JPEG, options, os);  
        // Compress by loop
        while ( os.toByteArray().length / 1024 > maxSize) {
            // Clean up os
        	os.reset();
        	// interval 10
            options -= 10;
            image.compress(Bitmap.CompressFormat.JPEG, options, os);
        }
        
        // Generate compressed image file
        FileOutputStream fos = new FileOutputStream(outPath);  
        fos.write(os.toByteArray());  
        fos.flush();  
        fos.close();  
	}
	
	/**
	 * Compress by quality,  and generate image to the path specified
	 * 
	 * @param imgPath
	 * @param outPath
	 * @param maxSize target will be compressed to be smaller than this size.(kb)
	 * @param needsDelete Whether delete original file after compress
	 * @throws IOException 
	 */
	public void compressAndGenImage(String imgPath, String outPath, int maxSize, boolean needsDelete) throws IOException {
		compressAndGenImage(getBitmap(imgPath), outPath, maxSize);
		
		// Delete original file
		if (needsDelete) {
			File file = new File (imgPath);
			if (file.exists()) {
				file.delete();
			}
		}
	}
	
	/**
	 * Ratio and generate thumb to the path specified
	 * 
	 * @param image
	 * @param outPath
	 * @param pixelW target pixel of width
	 * @param pixelH target pixel of height
	 * @throws FileNotFoundException
	 */
	public void ratioAndGenThumb(Bitmap image, String outPath, float pixelW, float pixelH) throws FileNotFoundException {
		Bitmap bitmap = ratio(image, pixelW, pixelH);
		storeImage( bitmap, outPath);
	}
	
	/**
	 * Ratio and generate thumb to the path specified
	 * 
	 * @param image
	 * @param outPath
	 * @param pixelW target pixel of width
	 * @param pixelH target pixel of height
	 * @param needsDelete Whether delete original file after compress
	 * @throws FileNotFoundException
	 */
	public void ratioAndGenThumb(String imgPath, String outPath, float pixelW, float pixelH, boolean needsDelete) throws FileNotFoundException {
		Bitmap bitmap = ratio(imgPath, pixelW, pixelH);
		storeImage( bitmap, outPath);
		
		// Delete original file
				if (needsDelete) {
					File file = new File (imgPath);
					if (file.exists()) {
						file.delete();
					}
				}
	}
	
}


如果上面的工具类不满足你,那么看看下面的方法。

一、图片质量压缩
  1. /** 
  2.  * 质量压缩方法 
  3.  * 
  4.  * @param image 
  5.  * @return 
  6.  */  
  7. public static Bitmap compressImage(Bitmap image) {  
  8.   
  9.     ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  10.     image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中  
  11.     int options = 90;  
  12.   
  13.     while (baos.toByteArray().length / 1024 > 100) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩  
  14.         baos.reset(); // 重置baos即清空baos  
  15.         image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中  
  16.         options -= 10;// 每次都减少10  
  17.     }  
  18.     ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中  
  19.     Bitmap bitmap = BitmapFactory.decodeStream(isBm, nullnull);// 把ByteArrayInputStream数据生成图片  
  20.     return bitmap;  
  21. }  
save_snippets.png
    /**
     * 质量压缩方法
     *
     * @param image
     * @return
     */
    public static Bitmap compressImage(Bitmap image) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
        int options = 90;

        while (baos.toByteArray().length / 1024 > 100) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset(); // 重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
            options -= 10;// 每次都减少10
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
        return bitmap;
    }

二、按比例大小压缩 (路径获取图片)

  1. /** 
  2.  * 图片按比例大小压缩方法 
  3.  * 
  4.  * @param srcPath (根据路径获取图片并压缩) 
  5.  * @return 
  6.  */  
  7. public static Bitmap getimage(String srcPath) {  
  8.   
  9.     BitmapFactory.Options newOpts = new BitmapFactory.Options();  
  10.     // 开始读入图片,此时把options.inJustDecodeBounds 设回true了  
  11.     newOpts.inJustDecodeBounds = true;  
  12.     Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空  
  13.   
  14.     newOpts.inJustDecodeBounds = false;  
  15.     int w = newOpts.outWidth;  
  16.     int h = newOpts.outHeight;  
  17.     // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为  
  18.     float hh = 800f;// 这里设置高度为800f  
  19.     float ww = 480f;// 这里设置宽度为480f  
  20.     // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可  
  21.     int be = 1;// be=1表示不缩放  
  22.     if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放  
  23.         be = (int) (newOpts.outWidth / ww);  
  24.     } else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放  
  25.         be = (int) (newOpts.outHeight / hh);  
  26.     }  
  27.     if (be <= 0)  
  28.         be = 1;  
  29.     newOpts.inSampleSize = be;// 设置缩放比例  
  30.     // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了  
  31.     bitmap = BitmapFactory.decodeFile(srcPath, newOpts);  
  32.     return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩  
  33. }  
save_snippets.png
    /**
     * 图片按比例大小压缩方法
     *
     * @param srcPath (根据路径获取图片并压缩)
     * @return
     */
    public static Bitmap getimage(String srcPath) {

        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        // 开始读入图片,此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空

        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
        float hh = 800f;// 这里设置高度为800f
        float ww = 480f;// 这里设置宽度为480f
        // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
        int be = 1;// be=1表示不缩放
        if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be;// 设置缩放比例
        // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
        bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
        return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩
    }
三、按比例大小压缩 (Bitmap)

  1. /** 
  2.  * 图片按比例大小压缩方法 
  3.  * 
  4.  * @param image (根据Bitmap图片压缩) 
  5.  * @return 
  6.  */  
  7. public static Bitmap compressScale(Bitmap image) {  
  8.   
  9.     ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  10.     image.compress(Bitmap.CompressFormat.JPEG, 100, baos);  
  11.   
  12.     // 判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出  
  13.     if (baos.toByteArray().length / 1024 > 1024) {  
  14.         baos.reset();// 重置baos即清空baos  
  15.         image.compress(Bitmap.CompressFormat.JPEG, 80, baos);// 这里压缩50%,把压缩后的数据存放到baos中  
  16.     }  
  17.     ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());  
  18.     BitmapFactory.Options newOpts = new BitmapFactory.Options();  
  19.     // 开始读入图片,此时把options.inJustDecodeBounds 设回true了  
  20.     newOpts.inJustDecodeBounds = true;  
  21.     Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);  
  22.     newOpts.inJustDecodeBounds = false;  
  23.     int w = newOpts.outWidth;  
  24.     int h = newOpts.outHeight;  
  25.     Log.i(TAG, w + "---------------" + h);  
  26.     // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为  
  27.     // float hh = 800f;// 这里设置高度为800f  
  28.     // float ww = 480f;// 这里设置宽度为480f  
  29.     float hh = 512f;  
  30.     float ww = 512f;  
  31.     // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可  
  32.     int be = 1;// be=1表示不缩放  
  33.     if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放  
  34.         be = (int) (newOpts.outWidth / ww);  
  35.     } else if (w < h && h > hh) { // 如果高度高的话根据高度固定大小缩放  
  36.         be = (int) (newOpts.outHeight / hh);  
  37.     }  
  38.     if (be <= 0)  
  39.         be = 1;  
  40.     newOpts.inSampleSize = be; // 设置缩放比例  
  41.     // newOpts.inPreferredConfig = Config.RGB_565;//降低图片从ARGB888到RGB565  
  42.   
  43.     // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了  
  44.     isBm = new ByteArrayInputStream(baos.toByteArray());  
  45.     bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);  
  46.   
  47.     return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩  
  48.   
  49.     //return bitmap;  
  50. }  
save_snippets.png
    /**
     * 图片按比例大小压缩方法
     *
     * @param image (根据Bitmap图片压缩)
     * @return
     */
    public static Bitmap compressScale(Bitmap image) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);

        // 判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
        if (baos.toByteArray().length / 1024 > 1024) {
            baos.reset();// 重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, 80, baos);// 这里压缩50%,把压缩后的数据存放到baos中
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        // 开始读入图片,此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        Log.i(TAG, w + "---------------" + h);
        // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
        // float hh = 800f;// 这里设置高度为800f
        // float ww = 480f;// 这里设置宽度为480f
        float hh = 512f;
        float ww = 512f;
        // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
        int be = 1;// be=1表示不缩放
        if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) { // 如果高度高的话根据高度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be; // 设置缩放比例
        // newOpts.inPreferredConfig = Config.RGB_565;//降低图片从ARGB888到RGB565

        // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
        isBm = new ByteArrayInputStream(baos.toByteArray());
        bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);

        return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩

        //return bitmap;
    }





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

分享个按照图片尺寸压缩:

  1. public static void compressPicture(String srcPath, String desPath) {  
  2.         FileOutputStream fos = null;  
  3.         BitmapFactory.Options op = new BitmapFactory.Options();  
  4.   
  5.         // 开始读入图片,此时把options.inJustDecodeBounds 设回true了  
  6.         op.inJustDecodeBounds = true;  
  7.         Bitmap bitmap = BitmapFactory.decodeFile(srcPath, op);  
  8.         op.inJustDecodeBounds = false;  
  9.   
  10.         // 缩放图片的尺寸  
  11.         float w = op.outWidth;  
  12.         float h = op.outHeight;  
  13.         float hh = 1024f;//  
  14.         float ww = 1024f;//  
  15.         // 最长宽度或高度1024  
  16.         float be = 1.0f;  
  17.         if (w > h && w > ww) {  
  18.             be = (float) (w / ww);  
  19.         } else if (w < h && h > hh) {  
  20.             be = (float) (h / hh);  
  21.         }  
  22.         if (be <= 0) {  
  23.             be = 1.0f;  
  24.         }  
  25.         op.inSampleSize = (int) be;// 设置缩放比例,这个数字越大,图片大小越小.  
  26.         // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了  
  27.         bitmap = BitmapFactory.decodeFile(srcPath, op);  
  28.         int desWidth = (int) (w / be);  
  29.         int desHeight = (int) (h / be);  
  30.         bitmap = Bitmap.createScaledBitmap(bitmap, desWidth, desHeight, true);  
  31.         try {  
  32.             fos = new FileOutputStream(desPath);  
  33.             if (bitmap != null) {  
  34.                 bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);  
  35.             }  
  36.         } catch (FileNotFoundException e) {  
  37.             e.printStackTrace();  
  38.         }  
  39.     }  
save_snippets.png
public static void compressPicture(String srcPath, String desPath) {
		FileOutputStream fos = null;
		BitmapFactory.Options op = new BitmapFactory.Options();

		// 开始读入图片,此时把options.inJustDecodeBounds 设回true了
		op.inJustDecodeBounds = true;
		Bitmap bitmap = BitmapFactory.decodeFile(srcPath, op);
		op.inJustDecodeBounds = false;

		// 缩放图片的尺寸
		float w = op.outWidth;
		float h = op.outHeight;
		float hh = 1024f;//
		float ww = 1024f;//
		// 最长宽度或高度1024
		float be = 1.0f;
		if (w > h && w > ww) {
			be = (float) (w / ww);
		} else if (w < h && h > hh) {
			be = (float) (h / hh);
		}
		if (be <= 0) {
			be = 1.0f;
		}
		op.inSampleSize = (int) be;// 设置缩放比例,这个数字越大,图片大小越小.
		// 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
		bitmap = BitmapFactory.decodeFile(srcPath, op);
		int desWidth = (int) (w / be);
		int desHeight = (int) (h / be);
		bitmap = Bitmap.createScaledBitmap(bitmap, desWidth, desHeight, true);
		try {
			fos = new FileOutputStream(desPath);
			if (bitmap != null) {
				bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}


需要注意两个问题:

一、调用getDrawingCache()前先要测量,否则的话得到的bitmap为null,这个我在OnCreate()、OnStart()、OnResume()方法里都试验过。


二、当调用bitmap.compress(CompressFormat.JPEG, 100, fos);保存为图片时发现图片背景为黑色,如下图:


这时只需要改成用png保存就可以了,bitmap.compress(CompressFormat.PNG, 100, fos);,如下图:



在实际开发中,有时候我们需求将文件转换为字符串,然后作为参数进行上传。

必备工具类图片bitmap转成字符串string与String字符串转换为bitmap图片格式

  1. import android.graphics.Bitmap;  
  2. import android.graphics.BitmapFactory;  
  3. import android.util.Base64;  
  4.   
  5. import java.io.ByteArrayOutputStream;  
  6.   
  7. /** 
  8.  *  
  9.  *  
  10.  * 功能描述:Android开发之常用必备工具类图片bitmap转成字符串string与String字符串转换为bitmap图片格式 
  11.  */  
  12. public class BitmapAndStringUtils {  
  13.     /** 
  14.      * 图片转成string 
  15.      * 
  16.      * @param bitmap 
  17.      * @return 
  18.      */  
  19.     public static String convertIconToString(Bitmap bitmap)  
  20.     {  
  21.         ByteArrayOutputStream baos = new ByteArrayOutputStream();// outputstream  
  22.         bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);  
  23.         byte[] appicon = baos.toByteArray();// 转为byte数组  
  24.         return Base64.encodeToString(appicon, Base64.DEFAULT);  
  25.   
  26.     }  
  27.   
  28.     /** 
  29.      * string转成bitmap 
  30.      * 
  31.      * @param st 
  32.      */  
  33.     public static Bitmap convertStringToIcon(String st)  
  34.     {  
  35.         // OutputStream out;  
  36.         Bitmap bitmap = null;  
  37.         try  
  38.         {  
  39.             // out = new FileOutputStream("/sdcard/aa.jpg");  
  40.             byte[] bitmapArray;  
  41.             bitmapArray = Base64.decode(st, Base64.DEFAULT);  
  42.             bitmap =  
  43.                     BitmapFactory.decodeByteArray(bitmapArray, 0,  
  44.                             bitmapArray.length);  
  45.             // bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);  
  46.             return bitmap;  
  47.         }  
  48.         catch (Exception e)  
  49.         {  
  50.             return null;  
  51.         }  
  52.     }  
  53. }  
save_snippets.png
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;

import java.io.ByteArrayOutputStream;

/**
 * 
 * 
 * 功能描述:Android开发之常用必备工具类图片bitmap转成字符串string与String字符串转换为bitmap图片格式
 */
public class BitmapAndStringUtils {
    /**
     * 图片转成string
     *
     * @param bitmap
     * @return
     */
    public static String convertIconToString(Bitmap bitmap)
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();// outputstream
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
        byte[] appicon = baos.toByteArray();// 转为byte数组
        return Base64.encodeToString(appicon, Base64.DEFAULT);

    }

    /**
     * string转成bitmap
     *
     * @param st
     */
    public static Bitmap convertStringToIcon(String st)
    {
        // OutputStream out;
        Bitmap bitmap = null;
        try
        {
            // out = new FileOutputStream("/sdcard/aa.jpg");
            byte[] bitmapArray;
            bitmapArray = Base64.decode(st, Base64.DEFAULT);
            bitmap =
                    BitmapFactory.decodeByteArray(bitmapArray, 0,
                            bitmapArray.length);
            // bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            return bitmap;
        }
        catch (Exception e)
        {
            return null;
        }
    }
}

如果你的图片是File文件,可以用下面代码:

  1. /** 
  2.  * 图片文件转换为指定编码的字符串 
  3.  * 
  4.  * @param imgFile  图片文件 
  5.  */  
  6. public static String file2String(File imgFile) {  
  7.     InputStream in = null;  
  8.     byte[] data = null;  
  9.     //读取图片字节数组  
  10.     try{  
  11.         in = new FileInputStream(imgFile);  
  12.         data = new byte[in.available()];  
  13.         in.read(data);  
  14.         in.close();  
  15.     } catch (IOException e){  
  16.         e.printStackTrace();  
  17.     }  
  18.     //对字节数组Base64编码  
  19.     BASE64Encoder encoder = new BASE64Encoder();  
  20.     String result = encoder.encode(data);  
  21.     return result;//返回Base64编码过的字节数组字符串  
  22. }  
save_snippets.png
    /**
     * 图片文件转换为指定编码的字符串
     *
     * @param imgFile  图片文件
     */
    public static String file2String(File imgFile) {
        InputStream in = null;
        byte[] data = null;
        //读取图片字节数组
        try{
            in = new FileInputStream(imgFile);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e){
            e.printStackTrace();
        }
        //对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        String result = encoder.encode(data);
        return result;//返回Base64编码过的字节数组字符串
    }



40
1
 
 

我的同类文章

在网上调查了图片压缩的方法并实装后,大致上可以认为有两类压缩:质量压缩(不改变图片的尺寸)和尺寸压缩(相当于是像素上的压缩);质量压缩一般可用于上传大图前的处理,这样就可以节省一定的流量,毕竟现在的手机拍照都能达到3M左右了,尺寸压缩一般可用于生成缩略图。
两种方法都实装在了我的项目中,结果却发现在质量压缩的模块中,本来1.9M的图片压缩后反而变成3M多了,很是奇怪,再做了进一步调查终于知道原因了。下面这个博客说的比较清晰:

android图片压缩总结

总结来看,图片有三种存在形式:硬盘上时是file,网络传输时是stream,内存中是stream或bitmap,所谓的质量压缩,它其实只能实现对file的影响,你可以把一个file转成bitmap再转成file,或者直接将一个bitmap转成file时,这个最终的file是被压缩过的,但是中间的bitmap并没有被压缩(或者说几乎没有被压缩,我不确定),因为bigmap在内存中的大小是按像素计算的,也就是width * height,对于质量压缩,并不会改变图片的像素,所以就算质量被压缩了,但是bitmap在内存的占有率还是没变小,但你做成file时,它确实变小了;

而尺寸压缩由于是减小了图片的像素,所以它直接对bitmap产生了影响,当然最终的file也是相对的变小了;

最后把自己总结的工具类贴出来:
  1. import java.io.ByteArrayInputStream;  
  2. import java.io.ByteArrayOutputStream;  
  3. import java.io.File;  
  4. import java.io.FileNotFoundException;  
  5. import java.io.FileOutputStream;  
  6. import java.io.IOException;  
  7.   
  8. import android.graphics.Bitmap;  
  9. import android.graphics.Bitmap.Config;  
  10. import android.graphics.BitmapFactory;  
  11.   
  12. /** 
  13.  * Image compress factory class 
  14.  *  
  15.  * @author  
  16.  * 
  17.  */  
  18. public class ImageFactory {  
  19.   
  20.     /** 
  21.      * Get bitmap from specified image path 
  22.      *  
  23.      * @param imgPath 
  24.      * @return 
  25.      */  
  26.     public Bitmap getBitmap(String imgPath) {  
  27.         // Get bitmap through image path  
  28.         BitmapFactory.Options newOpts = new BitmapFactory.Options();  
  29.         newOpts.inJustDecodeBounds = false;  
  30.         newOpts.inPurgeable = true;  
  31.         newOpts.inInputShareable = true;  
  32.         // Do not compress  
  33.         newOpts.inSampleSize = 1;  
  34.         newOpts.inPreferredConfig = Config.RGB_565;  
  35.         return BitmapFactory.decodeFile(imgPath, newOpts);  
  36.     }  
  37.       
  38.     /** 
  39.      * Store bitmap into specified image path 
  40.      *  
  41.      * @param bitmap 
  42.      * @param outPath 
  43.      * @throws FileNotFoundException  
  44.      */  
  45.     public void storeImage(Bitmap bitmap, String outPath) throws FileNotFoundException {  
  46.         FileOutputStream os = new FileOutputStream(outPath);  
  47.         bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);  
  48.     }  
  49.       
  50.     /** 
  51.      * Compress image by pixel, this will modify image width/height.  
  52.      * Used to get thumbnail 
  53.      *  
  54.      * @param imgPath image path 
  55.      * @param pixelW target pixel of width 
  56.      * @param pixelH target pixel of height 
  57.      * @return 
  58.      */  
  59.     public Bitmap ratio(String imgPath, float pixelW, float pixelH) {  
  60.         BitmapFactory.Options newOpts = new BitmapFactory.Options();    
  61.         // 开始读入图片,此时把options.inJustDecodeBounds 设回true,即只读边不读内容  
  62.         newOpts.inJustDecodeBounds = true;  
  63.         newOpts.inPreferredConfig = Config.RGB_565;  
  64.         // Get bitmap info, but notice that bitmap is null now    
  65.         Bitmap bitmap = BitmapFactory.decodeFile(imgPath,newOpts);  
  66.             
  67.         newOpts.inJustDecodeBounds = false;    
  68.         int w = newOpts.outWidth;    
  69.         int h = newOpts.outHeight;    
  70.         // 想要缩放的目标尺寸  
  71.         float hh = pixelH;// 设置高度为240f时,可以明显看到图片缩小了  
  72.         float ww = pixelW;// 设置宽度为120f,可以明显看到图片缩小了  
  73.         // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可    
  74.         int be = 1;//be=1表示不缩放    
  75.         if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放    
  76.             be = (int) (newOpts.outWidth / ww);    
  77.         } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放    
  78.             be = (int) (newOpts.outHeight / hh);    
  79.         }    
  80.         if (be <= 0) be = 1;    
  81.         newOpts.inSampleSize = be;//设置缩放比例  
  82.         // 开始压缩图片,注意此时已经把options.inJustDecodeBounds 设回false了  
  83.         bitmap = BitmapFactory.decodeFile(imgPath, newOpts);  
  84.         // 压缩好比例大小后再进行质量压缩  
  85. //        return compress(bitmap, maxSize); // 这里再进行质量压缩的意义不大,反而耗资源,删除  
  86.         return bitmap;  
  87.     }  
  88.       
  89.     /** 
  90.      * Compress image by size, this will modify image width/height.  
  91.      * Used to get thumbnail 
  92.      *  
  93.      * @param image 
  94.      * @param pixelW target pixel of width 
  95.      * @param pixelH target pixel of height 
  96.      * @return 
  97.      */  
  98.     public Bitmap ratio(Bitmap image, float pixelW, float pixelH) {  
  99.         ByteArrayOutputStream os = new ByteArrayOutputStream();  
  100.         image.compress(Bitmap.CompressFormat.JPEG, 100, os);  
  101.         if( os.toByteArray().length / 1024>1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出      
  102.             os.reset();//重置baos即清空baos    
  103.             image.compress(Bitmap.CompressFormat.JPEG, 50, os);//这里压缩50%,把压缩后的数据存放到baos中    
  104.         }    
  105.         ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());    
  106.         BitmapFactory.Options newOpts = new BitmapFactory.Options();    
  107.         //开始读入图片,此时把options.inJustDecodeBounds 设回true了    
  108.         newOpts.inJustDecodeBounds = true;  
  109.         newOpts.inPreferredConfig = Config.RGB_565;  
  110.         Bitmap bitmap = BitmapFactory.decodeStream(is, null, newOpts);    
  111.         newOpts.inJustDecodeBounds = false;    
  112.         int w = newOpts.outWidth;    
  113.         int h = newOpts.outHeight;    
  114.         float hh = pixelH;// 设置高度为240f时,可以明显看到图片缩小了  
  115.         float ww = pixelW;// 设置宽度为120f,可以明显看到图片缩小了  
  116.         //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可    
  117.         int be = 1;//be=1表示不缩放    
  118.         if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放    
  119.             be = (int) (newOpts.outWidth / ww);    
  120.         } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放    
  121.             be = (int) (newOpts.outHeight / hh);    
  122.         }    
  123.         if (be <= 0) be = 1;    
  124.         newOpts.inSampleSize = be;//设置缩放比例    
  125.         //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了    
  126.         is = new ByteArrayInputStream(os.toByteArray());    
  127.         bitmap = BitmapFactory.decodeStream(is, null, newOpts);  
  128.         //压缩好比例大小后再进行质量压缩  
  129. //      return compress(bitmap, maxSize); // 这里再进行质量压缩的意义不大,反而耗资源,删除  
  130.         return bitmap;  
  131.     }  
  132.       
  133.     /** 
  134.      * Compress by quality,  and generate image to the path specified 
  135.      *  
  136.      * @param image 
  137.      * @param outPath 
  138.      * @param maxSize target will be compressed to be smaller than this size.(kb) 
  139.      * @throws IOException  
  140.      */  
  141.     public void compressAndGenImage(Bitmap image, String outPath, int maxSize) throws IOException {  
  142.         ByteArrayOutputStream os = new ByteArrayOutputStream();  
  143.         // scale  
  144.         int options = 100;  
  145.         // Store the bitmap into output stream(no compress)  
  146.         image.compress(Bitmap.CompressFormat.JPEG, options, os);    
  147.         // Compress by loop  
  148.         while ( os.toByteArray().length / 1024 > maxSize) {  
  149.             // Clean up os  
  150.             os.reset();  
  151.             // interval 10  
  152.             options -= 10;  
  153.             image.compress(Bitmap.CompressFormat.JPEG, options, os);  
  154.         }  
  155.           
  156.         // Generate compressed image file  
  157.         FileOutputStream fos = new FileOutputStream(outPath);    
  158.         fos.write(os.toByteArray());    
  159.         fos.flush();    
  160.         fos.close();    
  161.     }  
  162.       
  163.     /** 
  164.      * Compress by quality,  and generate image to the path specified 
  165.      *  
  166.      * @param imgPath 
  167.      * @param outPath 
  168.      * @param maxSize target will be compressed to be smaller than this size.(kb) 
  169.      * @param needsDelete Whether delete original file after compress 
  170.      * @throws IOException  
  171.      */  
  172.     public void compressAndGenImage(String imgPath, String outPath, int maxSize, boolean needsDelete) throws IOException {  
  173.         compressAndGenImage(getBitmap(imgPath), outPath, maxSize);  
  174.           
  175.         // Delete original file  
  176.         if (needsDelete) {  
  177.             File file = new File (imgPath);  
  178.             if (file.exists()) {  
  179.                 file.delete();  
  180.             }  
  181.         }  
  182.     }  
  183.       
  184.     /** 
  185.      * Ratio and generate thumb to the path specified 
  186.      *  
  187.      * @param image 
  188.      * @param outPath 
  189.      * @param pixelW target pixel of width 
  190.      * @param pixelH target pixel of height 
  191.      * @throws FileNotFoundException 
  192.      */  
  193.     public void ratioAndGenThumb(Bitmap image, String outPath, float pixelW, float pixelH) throws FileNotFoundException {  
  194.         Bitmap bitmap = ratio(image, pixelW, pixelH);  
  195.         storeImage( bitmap, outPath);  
  196.     }  
  197.       
  198.     /** 
  199.      * Ratio and generate thumb to the path specified 
  200.      *  
  201.      * @param image 
  202.      * @param outPath 
  203.      * @param pixelW target pixel of width 
  204.      * @param pixelH target pixel of height 
  205.      * @param needsDelete Whether delete original file after compress 
  206.      * @throws FileNotFoundException 
  207.      */  
  208.     public void ratioAndGenThumb(String imgPath, String outPath, float pixelW, float pixelH, boolean needsDelete) throws FileNotFoundException {  
  209.         Bitmap bitmap = ratio(imgPath, pixelW, pixelH);  
  210.         storeImage( bitmap, outPath);  
  211.           
  212.         // Delete original file  
  213.                 if (needsDelete) {  
  214.                     File file = new File (imgPath);  
  215.                     if (file.exists()) {  
  216.                         file.delete();  
  217.                     }  
  218.                 }  
  219.     }  
  220.       
  221. }  
save_snippets.png
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;

/**
 * Image compress factory class
 * 
 * @author 
 *
 */
public class ImageFactory {

	/**
	 * Get bitmap from specified image path
	 * 
	 * @param imgPath
	 * @return
	 */
	public Bitmap getBitmap(String imgPath) {
		// Get bitmap through image path
		BitmapFactory.Options newOpts = new BitmapFactory.Options();
		newOpts.inJustDecodeBounds = false;
		newOpts.inPurgeable = true;
		newOpts.inInputShareable = true;
		// Do not compress
		newOpts.inSampleSize = 1;
		newOpts.inPreferredConfig = Config.RGB_565;
		return BitmapFactory.decodeFile(imgPath, newOpts);
	}
	
	/**
	 * Store bitmap into specified image path
	 * 
	 * @param bitmap
	 * @param outPath
	 * @throws FileNotFoundException 
	 */
	public void storeImage(Bitmap bitmap, String outPath) throws FileNotFoundException {
		FileOutputStream os = new FileOutputStream(outPath);
		bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
	}
	
	/**
	 * Compress image by pixel, this will modify image width/height. 
	 * Used to get thumbnail
	 * 
	 * @param imgPath image path
	 * @param pixelW target pixel of width
	 * @param pixelH target pixel of height
	 * @return
	 */
	public Bitmap ratio(String imgPath, float pixelW, float pixelH) {
		BitmapFactory.Options newOpts = new BitmapFactory.Options();  
        // 开始读入图片,此时把options.inJustDecodeBounds 设回true,即只读边不读内容
        newOpts.inJustDecodeBounds = true;
        newOpts.inPreferredConfig = Config.RGB_565;
        // Get bitmap info, but notice that bitmap is null now  
        Bitmap bitmap = BitmapFactory.decodeFile(imgPath,newOpts);
          
        newOpts.inJustDecodeBounds = false;  
        int w = newOpts.outWidth;  
        int h = newOpts.outHeight;  
        // 想要缩放的目标尺寸
        float hh = pixelH;// 设置高度为240f时,可以明显看到图片缩小了
	    float ww = pixelW;// 设置宽度为120f,可以明显看到图片缩小了
        // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可  
        int be = 1;//be=1表示不缩放  
        if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放  
            be = (int) (newOpts.outWidth / ww);  
        } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放  
            be = (int) (newOpts.outHeight / hh);  
        }  
        if (be <= 0) be = 1;  
        newOpts.inSampleSize = be;//设置缩放比例
        // 开始压缩图片,注意此时已经把options.inJustDecodeBounds 设回false了
        bitmap = BitmapFactory.decodeFile(imgPath, newOpts);
        // 压缩好比例大小后再进行质量压缩
//        return compress(bitmap, maxSize); // 这里再进行质量压缩的意义不大,反而耗资源,删除
        return bitmap;
	}
	
	/**
	 * Compress image by size, this will modify image width/height. 
	 * Used to get thumbnail
	 * 
	 * @param image
	 * @param pixelW target pixel of width
	 * @param pixelH target pixel of height
	 * @return
	 */
	public Bitmap ratio(Bitmap image, float pixelW, float pixelH) {
		ByteArrayOutputStream os = new ByteArrayOutputStream();
	    image.compress(Bitmap.CompressFormat.JPEG, 100, os);
	    if( os.toByteArray().length / 1024>1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出    
	        os.reset();//重置baos即清空baos  
	        image.compress(Bitmap.CompressFormat.JPEG, 50, os);//这里压缩50%,把压缩后的数据存放到baos中  
	    }  
	    ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());  
	    BitmapFactory.Options newOpts = new BitmapFactory.Options();  
	    //开始读入图片,此时把options.inJustDecodeBounds 设回true了  
	    newOpts.inJustDecodeBounds = true;
	    newOpts.inPreferredConfig = Config.RGB_565;
	    Bitmap bitmap = BitmapFactory.decodeStream(is, null, newOpts);  
	    newOpts.inJustDecodeBounds = false;  
	    int w = newOpts.outWidth;  
	    int h = newOpts.outHeight;  
	    float hh = pixelH;// 设置高度为240f时,可以明显看到图片缩小了
	    float ww = pixelW;// 设置宽度为120f,可以明显看到图片缩小了
	    //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可  
	    int be = 1;//be=1表示不缩放  
	    if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放  
	        be = (int) (newOpts.outWidth / ww);  
	    } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放  
	        be = (int) (newOpts.outHeight / hh);  
	    }  
	    if (be <= 0) be = 1;  
	    newOpts.inSampleSize = be;//设置缩放比例  
	    //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了  
	    is = new ByteArrayInputStream(os.toByteArray());  
	    bitmap = BitmapFactory.decodeStream(is, null, newOpts);
	    //压缩好比例大小后再进行质量压缩
//	    return compress(bitmap, maxSize); // 这里再进行质量压缩的意义不大,反而耗资源,删除
	    return bitmap;
	}
	
	/**
	 * Compress by quality,  and generate image to the path specified
	 * 
	 * @param image
	 * @param outPath
	 * @param maxSize target will be compressed to be smaller than this size.(kb)
	 * @throws IOException 
	 */
	public void compressAndGenImage(Bitmap image, String outPath, int maxSize) throws IOException {
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		// scale
		int options = 100;
		// Store the bitmap into output stream(no compress)
        image.compress(Bitmap.CompressFormat.JPEG, options, os);  
        // Compress by loop
        while ( os.toByteArray().length / 1024 > maxSize) {
            // Clean up os
        	os.reset();
        	// interval 10
            options -= 10;
            image.compress(Bitmap.CompressFormat.JPEG, options, os);
        }
        
        // Generate compressed image file
        FileOutputStream fos = new FileOutputStream(outPath);  
        fos.write(os.toByteArray());  
        fos.flush();  
        fos.close();  
	}
	
	/**
	 * Compress by quality,  and generate image to the path specified
	 * 
	 * @param imgPath
	 * @param outPath
	 * @param maxSize target will be compressed to be smaller than this size.(kb)
	 * @param needsDelete Whether delete original file after compress
	 * @throws IOException 
	 */
	public void compressAndGenImage(String imgPath, String outPath, int maxSize, boolean needsDelete) throws IOException {
		compressAndGenImage(getBitmap(imgPath), outPath, maxSize);
		
		// Delete original file
		if (needsDelete) {
			File file = new File (imgPath);
			if (file.exists()) {
				file.delete();
			}
		}
	}
	
	/**
	 * Ratio and generate thumb to the path specified
	 * 
	 * @param image
	 * @param outPath
	 * @param pixelW target pixel of width
	 * @param pixelH target pixel of height
	 * @throws FileNotFoundException
	 */
	public void ratioAndGenThumb(Bitmap image, String outPath, float pixelW, float pixelH) throws FileNotFoundException {
		Bitmap bitmap = ratio(image, pixelW, pixelH);
		storeImage( bitmap, outPath);
	}
	
	/**
	 * Ratio and generate thumb to the path specified
	 * 
	 * @param image
	 * @param outPath
	 * @param pixelW target pixel of width
	 * @param pixelH target pixel of height
	 * @param needsDelete Whether delete original file after compress
	 * @throws FileNotFoundException
	 */
	public void ratioAndGenThumb(String imgPath, String outPath, float pixelW, float pixelH, boolean needsDelete) throws FileNotFoundException {
		Bitmap bitmap = ratio(imgPath, pixelW, pixelH);
		storeImage( bitmap, outPath);
		
		// Delete original file
				if (needsDelete) {
					File file = new File (imgPath);
					if (file.exists()) {
						file.delete();
					}
				}
	}
	
}


如果上面的工具类不满足你,那么看看下面的方法。

一、图片质量压缩
  1. /** 
  2.  * 质量压缩方法 
  3.  * 
  4.  * @param image 
  5.  * @return 
  6.  */  
  7. public static Bitmap compressImage(Bitmap image) {  
  8.   
  9.     ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  10.     image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中  
  11.     int options = 90;  
  12.   
  13.     while (baos.toByteArray().length / 1024 > 100) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩  
  14.         baos.reset(); // 重置baos即清空baos  
  15.         image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中  
  16.         options -= 10;// 每次都减少10  
  17.     }  
  18.     ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中  
  19.     Bitmap bitmap = BitmapFactory.decodeStream(isBm, nullnull);// 把ByteArrayInputStream数据生成图片  
  20.     return bitmap;  
  21. }  
save_snippets.png
    /**
     * 质量压缩方法
     *
     * @param image
     * @return
     */
    public static Bitmap compressImage(Bitmap image) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
        int options = 90;

        while (baos.toByteArray().length / 1024 > 100) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
            baos.reset(); // 重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
            options -= 10;// 每次都减少10
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
        return bitmap;
    }

二、按比例大小压缩 (路径获取图片)

  1. /** 
  2.  * 图片按比例大小压缩方法 
  3.  * 
  4.  * @param srcPath (根据路径获取图片并压缩) 
  5.  * @return 
  6.  */  
  7. public static Bitmap getimage(String srcPath) {  
  8.   
  9.     BitmapFactory.Options newOpts = new BitmapFactory.Options();  
  10.     // 开始读入图片,此时把options.inJustDecodeBounds 设回true了  
  11.     newOpts.inJustDecodeBounds = true;  
  12.     Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空  
  13.   
  14.     newOpts.inJustDecodeBounds = false;  
  15.     int w = newOpts.outWidth;  
  16.     int h = newOpts.outHeight;  
  17.     // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为  
  18.     float hh = 800f;// 这里设置高度为800f  
  19.     float ww = 480f;// 这里设置宽度为480f  
  20.     // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可  
  21.     int be = 1;// be=1表示不缩放  
  22.     if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放  
  23.         be = (int) (newOpts.outWidth / ww);  
  24.     } else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放  
  25.         be = (int) (newOpts.outHeight / hh);  
  26.     }  
  27.     if (be <= 0)  
  28.         be = 1;  
  29.     newOpts.inSampleSize = be;// 设置缩放比例  
  30.     // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了  
  31.     bitmap = BitmapFactory.decodeFile(srcPath, newOpts);  
  32.     return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩  
  33. }  
save_snippets.png
    /**
     * 图片按比例大小压缩方法
     *
     * @param srcPath (根据路径获取图片并压缩)
     * @return
     */
    public static Bitmap getimage(String srcPath) {

        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        // 开始读入图片,此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);// 此时返回bm为空

        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
        float hh = 800f;// 这里设置高度为800f
        float ww = 480f;// 这里设置宽度为480f
        // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
        int be = 1;// be=1表示不缩放
        if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) {// 如果高度高的话根据宽度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be;// 设置缩放比例
        // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
        bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
        return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩
    }
三、按比例大小压缩 (Bitmap)

  1. /** 
  2.  * 图片按比例大小压缩方法 
  3.  * 
  4.  * @param image (根据Bitmap图片压缩) 
  5.  * @return 
  6.  */  
  7. public static Bitmap compressScale(Bitmap image) {  
  8.   
  9.     ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  10.     image.compress(Bitmap.CompressFormat.JPEG, 100, baos);  
  11.   
  12.     // 判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出  
  13.     if (baos.toByteArray().length / 1024 > 1024) {  
  14.         baos.reset();// 重置baos即清空baos  
  15.         image.compress(Bitmap.CompressFormat.JPEG, 80, baos);// 这里压缩50%,把压缩后的数据存放到baos中  
  16.     }  
  17.     ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());  
  18.     BitmapFactory.Options newOpts = new BitmapFactory.Options();  
  19.     // 开始读入图片,此时把options.inJustDecodeBounds 设回true了  
  20.     newOpts.inJustDecodeBounds = true;  
  21.     Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);  
  22.     newOpts.inJustDecodeBounds = false;  
  23.     int w = newOpts.outWidth;  
  24.     int h = newOpts.outHeight;  
  25.     Log.i(TAG, w + "---------------" + h);  
  26.     // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为  
  27.     // float hh = 800f;// 这里设置高度为800f  
  28.     // float ww = 480f;// 这里设置宽度为480f  
  29.     float hh = 512f;  
  30.     float ww = 512f;  
  31.     // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可  
  32.     int be = 1;// be=1表示不缩放  
  33.     if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放  
  34.         be = (int) (newOpts.outWidth / ww);  
  35.     } else if (w < h && h > hh) { // 如果高度高的话根据高度固定大小缩放  
  36.         be = (int) (newOpts.outHeight / hh);  
  37.     }  
  38.     if (be <= 0)  
  39.         be = 1;  
  40.     newOpts.inSampleSize = be; // 设置缩放比例  
  41.     // newOpts.inPreferredConfig = Config.RGB_565;//降低图片从ARGB888到RGB565  
  42.   
  43.     // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了  
  44.     isBm = new ByteArrayInputStream(baos.toByteArray());  
  45.     bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);  
  46.   
  47.     return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩  
  48.   
  49.     //return bitmap;  
  50. }  
save_snippets.png
    /**
     * 图片按比例大小压缩方法
     *
     * @param image (根据Bitmap图片压缩)
     * @return
     */
    public static Bitmap compressScale(Bitmap image) {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);

        // 判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
        if (baos.toByteArray().length / 1024 > 1024) {
            baos.reset();// 重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, 80, baos);// 这里压缩50%,把压缩后的数据存放到baos中
        }
        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        // 开始读入图片,此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        Log.i(TAG, w + "---------------" + h);
        // 现在主流手机比较多是800*480分辨率,所以高和宽我们设置为
        // float hh = 800f;// 这里设置高度为800f
        // float ww = 480f;// 这里设置宽度为480f
        float hh = 512f;
        float ww = 512f;
        // 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
        int be = 1;// be=1表示不缩放
        if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) { // 如果高度高的话根据高度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0)
            be = 1;
        newOpts.inSampleSize = be; // 设置缩放比例
        // newOpts.inPreferredConfig = Config.RGB_565;//降低图片从ARGB888到RGB565

        // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
        isBm = new ByteArrayInputStream(baos.toByteArray());
        bitmap = BitmapFactory.decodeStream(isBm, null, newOpts);

        return compressImage(bitmap);// 压缩好比例大小后再进行质量压缩

        //return bitmap;
    }





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

分享个按照图片尺寸压缩:

  1. public static void compressPicture(String srcPath, String desPath) {  
  2.         FileOutputStream fos = null;  
  3.         BitmapFactory.Options op = new BitmapFactory.Options();  
  4.   
  5.         // 开始读入图片,此时把options.inJustDecodeBounds 设回true了  
  6.         op.inJustDecodeBounds = true;  
  7.         Bitmap bitmap = BitmapFactory.decodeFile(srcPath, op);  
  8.         op.inJustDecodeBounds = false;  
  9.   
  10.         // 缩放图片的尺寸  
  11.         float w = op.outWidth;  
  12.         float h = op.outHeight;  
  13.         float hh = 1024f;//  
  14.         float ww = 1024f;//  
  15.         // 最长宽度或高度1024  
  16.         float be = 1.0f;  
  17.         if (w > h && w > ww) {  
  18.             be = (float) (w / ww);  
  19.         } else if (w < h && h > hh) {  
  20.             be = (float) (h / hh);  
  21.         }  
  22.         if (be <= 0) {  
  23.             be = 1.0f;  
  24.         }  
  25.         op.inSampleSize = (int) be;// 设置缩放比例,这个数字越大,图片大小越小.  
  26.         // 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了  
  27.         bitmap = BitmapFactory.decodeFile(srcPath, op);  
  28.         int desWidth = (int) (w / be);  
  29.         int desHeight = (int) (h / be);  
  30.         bitmap = Bitmap.createScaledBitmap(bitmap, desWidth, desHeight, true);  
  31.         try {  
  32.             fos = new FileOutputStream(desPath);  
  33.             if (bitmap != null) {  
  34.                 bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);  
  35.             }  
  36.         } catch (FileNotFoundException e) {  
  37.             e.printStackTrace();  
  38.         }  
  39.     }  
save_snippets.png
public static void compressPicture(String srcPath, String desPath) {
		FileOutputStream fos = null;
		BitmapFactory.Options op = new BitmapFactory.Options();

		// 开始读入图片,此时把options.inJustDecodeBounds 设回true了
		op.inJustDecodeBounds = true;
		Bitmap bitmap = BitmapFactory.decodeFile(srcPath, op);
		op.inJustDecodeBounds = false;

		// 缩放图片的尺寸
		float w = op.outWidth;
		float h = op.outHeight;
		float hh = 1024f;//
		float ww = 1024f;//
		// 最长宽度或高度1024
		float be = 1.0f;
		if (w > h && w > ww) {
			be = (float) (w / ww);
		} else if (w < h && h > hh) {
			be = (float) (h / hh);
		}
		if (be <= 0) {
			be = 1.0f;
		}
		op.inSampleSize = (int) be;// 设置缩放比例,这个数字越大,图片大小越小.
		// 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
		bitmap = BitmapFactory.decodeFile(srcPath, op);
		int desWidth = (int) (w / be);
		int desHeight = (int) (h / be);
		bitmap = Bitmap.createScaledBitmap(bitmap, desWidth, desHeight, true);
		try {
			fos = new FileOutputStream(desPath);
			if (bitmap != null) {
				bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}


需要注意两个问题:

一、调用getDrawingCache()前先要测量,否则的话得到的bitmap为null,这个我在OnCreate()、OnStart()、OnResume()方法里都试验过。


二、当调用bitmap.compress(CompressFormat.JPEG, 100, fos);保存为图片时发现图片背景为黑色,如下图:


这时只需要改成用png保存就可以了,bitmap.compress(CompressFormat.PNG, 100, fos);,如下图:



在实际开发中,有时候我们需求将文件转换为字符串,然后作为参数进行上传。

必备工具类图片bitmap转成字符串string与String字符串转换为bitmap图片格式

  1. import android.graphics.Bitmap;  
  2. import android.graphics.BitmapFactory;  
  3. import android.util.Base64;  
  4.   
  5. import java.io.ByteArrayOutputStream;  
  6.   
  7. /** 
  8.  *  
  9.  *  
  10.  * 功能描述:Android开发之常用必备工具类图片bitmap转成字符串string与String字符串转换为bitmap图片格式 
  11.  */  
  12. public class BitmapAndStringUtils {  
  13.     /** 
  14.      * 图片转成string 
  15.      * 
  16.      * @param bitmap 
  17.      * @return 
  18.      */  
  19.     public static String convertIconToString(Bitmap bitmap)  
  20.     {  
  21.         ByteArrayOutputStream baos = new ByteArrayOutputStream();// outputstream  
  22.         bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);  
  23.         byte[] appicon = baos.toByteArray();// 转为byte数组  
  24.         return Base64.encodeToString(appicon, Base64.DEFAULT);  
  25.   
  26.     }  
  27.   
  28.     /** 
  29.      * string转成bitmap 
  30.      * 
  31.      * @param st 
  32.      */  
  33.     public static Bitmap convertStringToIcon(String st)  
  34.     {  
  35.         // OutputStream out;  
  36.         Bitmap bitmap = null;  
  37.         try  
  38.         {  
  39.             // out = new FileOutputStream("/sdcard/aa.jpg");  
  40.             byte[] bitmapArray;  
  41.             bitmapArray = Base64.decode(st, Base64.DEFAULT);  
  42.             bitmap =  
  43.                     BitmapFactory.decodeByteArray(bitmapArray, 0,  
  44.                             bitmapArray.length);  
  45.             // bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);  
  46.             return bitmap;  
  47.         }  
  48.         catch (Exception e)  
  49.         {  
  50.             return null;  
  51.         }  
  52.     }  
  53. }  
save_snippets.png
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;

import java.io.ByteArrayOutputStream;

/**
 * 
 * 
 * 功能描述:Android开发之常用必备工具类图片bitmap转成字符串string与String字符串转换为bitmap图片格式
 */
public class BitmapAndStringUtils {
    /**
     * 图片转成string
     *
     * @param bitmap
     * @return
     */
    public static String convertIconToString(Bitmap bitmap)
    {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();// outputstream
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
        byte[] appicon = baos.toByteArray();// 转为byte数组
        return Base64.encodeToString(appicon, Base64.DEFAULT);

    }

    /**
     * string转成bitmap
     *
     * @param st
     */
    public static Bitmap convertStringToIcon(String st)
    {
        // OutputStream out;
        Bitmap bitmap = null;
        try
        {
            // out = new FileOutputStream("/sdcard/aa.jpg");
            byte[] bitmapArray;
            bitmapArray = Base64.decode(st, Base64.DEFAULT);
            bitmap =
                    BitmapFactory.decodeByteArray(bitmapArray, 0,
                            bitmapArray.length);
            // bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            return bitmap;
        }
        catch (Exception e)
        {
            return null;
        }
    }
}

如果你的图片是File文件,可以用下面代码:

  1. /** 
  2.  * 图片文件转换为指定编码的字符串 
  3.  * 
  4.  * @param imgFile  图片文件 
  5.  */  
  6. public static String file2String(File imgFile) {  
  7.     InputStream in = null;  
  8.     byte[] data = null;  
  9.     //读取图片字节数组  
  10.     try{  
  11.         in = new FileInputStream(imgFile);  
  12.         data = new byte[in.available()];  
  13.         in.read(data);  
  14.         in.close();  
  15.     } catch (IOException e){  
  16.         e.printStackTrace();  
  17.     }  
  18.     //对字节数组Base64编码  
  19.     BASE64Encoder encoder = new BASE64Encoder();  
  20.     String result = encoder.encode(data);  
  21.     return result;//返回Base64编码过的字节数组字符串  
  22. }  
save_snippets.png
    /**
     * 图片文件转换为指定编码的字符串
     *
     * @param imgFile  图片文件
     */
    public static String file2String(File imgFile) {
        InputStream in = null;
        byte[] data = null;
        //读取图片字节数组
        try{
            in = new FileInputStream(imgFile);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e){
            e.printStackTrace();
        }
        //对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        String result = encoder.encode(data);
        return result;//返回Base64编码过的字节数组字符串
    }



猜你喜欢

转载自blog.csdn.net/xy4_android/article/details/56009700