转自:
1 package com.testbitmapscale; 2 import java.io.File; 3 import java.io.FileInputStream; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.util.Iterator; 8 import com.testbitmapscale.R.drawable; 9 import android.app.Activity; 10 import android.graphics.Bitmap; 11 import android.graphics.Bitmap.Config; 12 import android.graphics.BitmapFactory; 13 import android.graphics.Canvas; 14 import android.graphics.Matrix; 15 import android.graphics.Paint; 16 import android.graphics.PorterDuff.Mode; 17 import android.graphics.PorterDuffXfermode; 18 import android.graphics.Rect; 19 import android.graphics.RectF; 20 import android.graphics.drawable.BitmapDrawable; 21 import android.graphics.drawable.Drawable; 22 import android.media.ThumbnailUtils; 23 import android.os.Bundle; 24 import android.os.Environment; 25 import android.view.View; 26 import android.widget.ImageView; 27 //方法: 28 //1 生成圆角Bitmap图片 29 //2 生成Bitmap缩量图 30 //3 压缩图片场长宽以及kB 31 //注意: 32 //以上代码,测试其中一个方法时最好注释掉其余的代码 33 public class MainActivity extends Activity { 34 private ImageView imageView; 35 private Bitmap copyRawBitmap1; 36 private Bitmap copyRawBitmap2; 37 private Bitmap copyRawBitmap3; 38 @Override 39 public void onCreate(Bundle savedInstanceState) { 40 super.onCreate(savedInstanceState); 41 setContentView(R.layout.main); 42 imageView = (ImageView) findViewById(R.id.imageView); 43 //第一种方式:从资源文件中得到图片 44 Bitmap rawBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.haha); 45 copyRawBitmap1=rawBitmap; 46 copyRawBitmap2=rawBitmap; 47 copyRawBitmap3=rawBitmap; 48 //第二种方式:从SD卡中得到图片(方法1) 49 String SDCarePath=Environment.getExternalStorageDirectory().toString(); 50 String filePath=SDCarePath+"/"+"haha.jpg"; 51 Bitmap rawBitmap1 = BitmapFactory.decodeFile(filePath, null); 52 //第二种方式:从SD卡中得到图片(方法2) 53 InputStream inputStream=getBitmapInputStreamFromSDCard("haha.jpg"); 54 Bitmap rawBitmap2 = BitmapFactory.decodeStream(inputStream); 55 56 //————>以下为将设置图片的圆角 57 Bitmap roundCornerBitmap=this.toRoundCorner(rawBitmap, 40); 58 imageView.setImageBitmap(roundCornerBitmap); 59 //————>以上为将设置图片的圆角 60 61 //————>以下为将图片高宽和的大小kB压缩 62 // 得到图片原始的高宽 63 int rawHeight = rawBitmap.getHeight(); 64 int rawWidth = rawBitmap.getWidth(); 65 // 设定图片新的高宽 66 int newHeight = 500; 67 int newWidth = 500; 68 // 计算缩放因子 69 float heightScale = ((float) newHeight) / rawHeight; 70 float widthScale = ((float) newWidth) / rawWidth; 71 // 新建立矩阵 72 Matrix matrix = new Matrix(); 73 matrix.postScale(heightScale, widthScale); 74 // 设置图片的旋转角度 75 //matrix.postRotate(-30); 76 // 设置图片的倾斜 77 //matrix.postSkew(0.1f, 0.1f); 78 //将图片大小压缩 79 //压缩后图片的宽和高以及kB大小均会变化 80 Bitmap newBitmap = Bitmap.createBitmap(rawBitmap, 0, 0, rawWidth,rawWidth, matrix, true); 81 // 将Bitmap转换为Drawable 82 Drawable newBitmapDrawable = new BitmapDrawable(newBitmap); 83 imageView.setImageDrawable(newBitmapDrawable); 84 //然后将Bitmap保存到SDCard中,方便于原图片的比较 85 this.compressAndSaveBitmapToSDCard(newBitmap, "xx100.jpg", 80); 86 //问题: 87 //原图大小为625x690 90.2kB 88 //如果设置图片500x500 压缩后大小为171kB.即压缩后kB反而变大了. 89 //原因是将:compress(Bitmap.CompressFormat.JPEG, quality, fileOutputStream); 90 //第二个参数quality设置得有些大了(比如100). 91 //常用的是80,刚设100太大了造成的. 92 //————>以上为将图片高宽和的大小kB压缩 93 94 95 //————>以下为将图片的kB压缩,宽高不变 96 this.compressAndSaveBitmapToSDCard(copyRawBitmap1,"0011fa.jpg",80); 97 //————>以上为将图片的kB压缩,宽高不变 98 99 //————>以下为获取SD卡图片的缩略图方法1 100 String SDCarePath1=Environment.getExternalStorageDirectory().toString(); 101 String filePath1=SDCarePath1+"/"+"haha.jpg"; 102 Bitmap bitmapThumbnail1=this.getBitmapThumbnail(filePath1); 103 imageView.setImageBitmap(bitmapThumbnail1); 104 //————>以上为获取SD卡图片的缩略图方法1 105 106 //————>以下为获取SD卡图片的缩略图方法2 107 String SDCarePath2=Environment.getExternalStorageDirectory().toString(); 108 String filePath2=SDCarePath2+"/"+"haha.jpg"; 109 Bitmap tempBitmap=BitmapFactory.decodeFile(filePath2); 110 Bitmap bitmapThumbnail2=ThumbnailUtils.extractThumbnail(tempBitmap, 100, 100); 111 imageView.setImageBitmap(bitmapThumbnail2); 112 //————>以上为获取SD卡图片的缩略图方法2 113 114 } 115 //读取SD卡下的图片 116 private InputStream getBitmapInputStreamFromSDCard(String fileName){ 117 if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { 118 String SDCarePath=Environment.getExternalStorageDirectory().toString(); 119 String filePath=SDCarePath+File.separator+fileName; 120 File file=new File(filePath); 121 try { 122 FileInputStream fileInputStream=new FileInputStream(file); 123 return fileInputStream; 124 } catch (Exception e) { 125 e.printStackTrace(); 126 } 127 128 } 129 return null; 130 } 131 132 133 //获取SDCard的目录路径功能 134 private String getSDCardPath() { 135 String SDCardPath = null; 136 // 判断SDCard是否存在 137 boolean IsSDcardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); 138 if (IsSDcardExist) { 139 SDCardPath = Environment.getExternalStorageDirectory().toString(); 140 } 141 return SDCardPath; 142 } 143 //压缩且保存图片到SDCard 144 private void compressAndSaveBitmapToSDCard(Bitmap rawBitmap,String fileName,int quality){ 145 String saveFilePaht=this.getSDCardPath()+File.separator+fileName; 146 File saveFile=new File(saveFilePaht); 147 if (!saveFile.exists()) { 148 try { 149 saveFile.createNewFile(); 150 FileOutputStream fileOutputStream=new FileOutputStream(saveFile); 151 if (fileOutputStream!=null) { 152 //imageBitmap.compress(format, quality, stream); 153 //把位图的压缩信息写入到一个指定的输出流中 154 //第一个参数format为压缩的格式 155 //第二个参数quality为图像压缩比的值,0-100.0 意味着小尺寸压缩,100意味着高质量压缩 156 //第三个参数stream为输出流 157 rawBitmap.compress(Bitmap.CompressFormat.JPEG, quality, fileOutputStream); 158 } 159 fileOutputStream.flush(); 160 fileOutputStream.close(); 161 } catch (IOException e) { 162 e.printStackTrace(); 163 164 } 165 } 166 } 167 168 //获取图片的缩略图 169 private Bitmap getBitmapThumbnail(String filePath){ 170 BitmapFactory.Options options=new BitmapFactory.Options(); 171 //true那么将不返回实际的bitmap对象,不给其分配内存空间但是可以得到一些解码边界信息即图片大小等信息 172 options.inJustDecodeBounds=true; 173 //此时rawBitmap为null 174 Bitmap rawBitmap = BitmapFactory.decodeFile(filePath, options); 175 if (rawBitmap==null) { 176 System.out.println("此时rawBitmap为null"); 177 } 178 //inSampleSize表示缩略图大小为原始图片大小的几分之一,若该值为3 179 //则取出的缩略图的宽和高都是原始图片的1/3,图片大小就为原始大小的1/9 180 //计算sampleSize 181 int sampleSize=computeSampleSize(options, 150, 200*200); 182 //为了读到图片,必须把options.inJustDecodeBounds设回false 183 options.inJustDecodeBounds = false; 184 options.inSampleSize = sampleSize; 185 //原图大小为625x690 90.2kB 186 //测试调用computeSampleSize(options, 100, 200*100); 187 //得到sampleSize=8 188 //得到宽和高位79和87 189 //79*8=632 87*8=696 190 Bitmap thumbnailBitmap=BitmapFactory.decodeFile(filePath, options); 191 //保存到SD卡方便比较 192 this.compressAndSaveBitmapToSDCard(thumbnailBitmap, "15.jpg", 80); 193 return thumbnailBitmap; 194 } 195 196 //参考资料: 197 //http://my.csdn.net/zljk000/code/detail/18212 198 //第一个参数:原本Bitmap的options 199 //第二个参数:希望生成的缩略图的宽高中的较小的值 200 //第三个参数:希望生成的缩量图的总像素 201 public static int computeSampleSize(BitmapFactory.Options options,int minSideLength, int maxNumOfPixels) { 202 int initialSize = computeInitialSampleSize(options, minSideLength,maxNumOfPixels); 203 int roundedSize; 204 if (initialSize <= 8) { 205 roundedSize = 1; 206 while (roundedSize < initialSize) { 207 roundedSize <<= 1; 208 } 209 } else { 210 roundedSize = (initialSize + 7) / 8 * 8; 211 } 212 return roundedSize; 213 } 214 215 private static int computeInitialSampleSize(BitmapFactory.Options options,int minSideLength, int maxNumOfPixels) { 216 //原始图片的宽 217 double w = options.outWidth; 218 //原始图片的高 219 double h = options.outHeight; 220 System.out.println("========== w="+w+",h="+h); 221 int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math 222 .sqrt(w * h / maxNumOfPixels)); 223 int upperBound = (minSideLength == -1) ? 128 : (int) Math.min( 224 Math.floor(w / minSideLength), Math.floor(h / minSideLength)); 225 if (upperBound < lowerBound) { 226 // return the larger one when there is no overlapping zone. 227 return lowerBound; 228 } 229 if ((maxNumOfPixels == -1) && (minSideLength == -1)) { 230 return 1; 231 } else if (minSideLength == -1) { 232 return lowerBound; 233 } else { 234 return upperBound; 235 } 236 } 237 238 /** 239 * @param bitmap 需要修改的图片 240 * @param pixels 圆角的弧度 241 * @return 圆角图片 242 */ 243 //参考资料: 244 //http://blog.csdn.net/c8822882/article/details/6906768 245 public Bitmap toRoundCorner(Bitmap bitmap, int pixels) { 246 Bitmap roundCornerBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888); 247 Canvas canvas = new Canvas(roundCornerBitmap); 248 int color = 0xff424242;//int color = 0xff424242; 249 Paint paint = new Paint(); 250 paint.setColor(color); 251 //防止锯齿 252 paint.setAntiAlias(true); 253 Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); 254 RectF rectF = new RectF(rect); 255 float roundPx = pixels; 256 //相当于清屏 257 canvas.drawARGB(0, 0, 0, 0); 258 //先画了一个带圆角的矩形 259 canvas.drawRoundRect(rectF, roundPx, roundPx, paint); 260 paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); 261 //再把原来的bitmap画到现在的bitmap!!!注意这个理解 262 canvas.drawBitmap(bitmap, rect, rect, paint); 263 return roundCornerBitmap; 264 } 265 266 }