目标:从sdcard中读取图片,并按一定的比例进行缩放,并保存到应用程序的目录下,同时通过ImageView显示保存的图片
分析:
android的文件系统与Linux的文件系统是一致的,但是出于一种安全的考虑,应用程序不能随意地创建文件和目录,也就是说应用程序不能随意跨越自己程序的边界,因此,应用程序一般只允许在自身程序的目录下才能进行自由的文件操作。通过Eclipse的DDMS视图可以看到android的应用程序的位置是 /data/data/,而文件则保存在 /data/data//files/目录下。
至于图片压缩,简单是说是按图片按比例进行缩放,android貌似只提供了一个android.graphics.Bitmap类来进行图片处理,所有的格式(png jpg gif)都可以用Bitmap来表示和存储。
代码:
public voidWriteFileEx() {
try {
//获取源图片的大小
Bitmap bm;
BitmapFactory.Optionsopts = new BitmapFactory.Options();
//当opts不为null时,但decodeFile返回空,不为图片分配内存,只获取图片的大小,并保存在opts的outWidth和outHeight
BitmapFactory.decodeFile("/sdcard/Stephen.jpg"opts);
intsrcWidth = opts.outWidth;
intsrcHeight = opts.outHeight;
intdestWidth = 0;
intdestHeight = 0;
//缩放的比例
doubleratio = 0.0;
//tvInfo是一个TextView用于显示图片的尺寸信息
tvInfo.setText("Width:"+ srcWidth + " Height:" + srcHeight);
//按比例计算缩放后的图片大小,maxLength是长或宽允许的最大长度
if(srcWidth>srcHeight) {
ratio =srcWidth / maxLength;
destWidth =maxLength;
destHeight= (int) (srcHeight / ratio);
}
else {
ratio =srcHeight / maxLength;
destHeight= maxLength;
destWidth =(int) (srcWidth / ratio);
}
//对图片进行压缩,是在读取的过程中进行压缩,而不是把图片读进了内存再进行压缩
BitmapFactory.OptionsnewOpts = new BitmapFactory.Options();
//缩放的比例,缩放是很难按准备的比例进行缩放的,目前我只发现只能通过inSampleSize来进行缩放,其值表明缩放的倍数,SDK中建议其值是2的指数值
newOpts.inSampleSize= (int) ratio + 1;
//inJustDecodeBounds设为false表示把图片读进内存中
newOpts.inJustDecodeBounds= false;
//设置大小,这个一般是不准确的,是以inSampleSize的为准,但是如果不设置却不能缩放
newOpts.outHeight= destHeight;
newOpts.outWidth= destWidth;
//添加尺寸信息,
tvInfo.append("\nWidth:"+ newOpts.outWidth + " Height:" + newOpts.outHeight);
//获取缩放后图片
BitmapdestBm = BitmapFactory.decodeFile("/sdcard/Stephen.jpg" newOpts);
if(destBm== null) {
showAlert("CreateFile"0 "Create Failed" "OK" false);
} else {
//文件命名,通过GUID可避免命名的重复
StringfileName = java.util.UUID.randomUUID().toString() + ".jpg";
//另外定义:
//ConfigManager.photoDir= getFileStreamPath(photoDirName)
//StringphotoDirName = "photo";要注意是根目录
FiledestFile = new File(ConfigManager.photoDir fileName);
//创建文件输出流
OutputStreamos = new FileOutputStream(destFile);
//存储
destBm.compress(CompressFormat.JPEG100 os);
//关闭流
os.close();
//显示图片
//setImgView(fileName);
//setDrawable(fileName);
setDrawableAbsolute(fileName);
}
}catch(Exception e) {
showAlert("CreateFile"0 e.toString() "OK" false);
}
}
显示图片有多种方式,通过ImageView,可以用Bitmap或者是用Drawable来进行显示。下面的imgView是一个ImageView的引用。
Bitmap通过输入流的方式显示:
public voidsetImgView(String fileName) {
try
{
File file =new File(ConfigManager.photoDir fileName);
InputStreamis = new FileInputStream(file);
Bitmap bm =BitmapFactory.decodeStream(is);
if (bm !=null) {
imgView.setImageBitmap(bm);
} else {
showAlert("CreateFile"0 "Set Failed" "OK" false);
}
is.close();
}catch(Exception e) {
showAlert("CreateFile"0 e.toString() "OK" false);
}
}
Drawable通过输入流的方式显示:
public voidsetDrawable(String fileName) {
try {
File file =new File(ConfigManager.photoDir fileName);
InputStreamis = new FileInputStream(file);
Drawable da= Drawable.createFromStream(is null);
if (da !=null) {
imgView.setImageDrawable(da);
} else {
showAlert("CreateFile"0 "Set Failed" "OK" false);
}
is.close();
}catch(Exception e) {
showAlert("CreateFile"0 e.toString() "OK" false);
}
}
直接通过Drawable进行显示:
public voidsetDrawableAbsolute(String fileName) {
try {
File file =new File(ConfigManager.photoDir fileName);
Drawable da= Drawable.createFromPath(file.getAbsolutePath());
if (da !=null) {
imgView.setImageDrawable(da);
} else {
showAlert("CreateFile"0 "Set Failed" "OK" false);
}
}catch(Exception e) {
showAlert("CreateFile"0 e.toString() "OK" false);
}
}
总的来说,在应用程序的作用域范围内android还是可以比较灵活地进行文件操作,不过可能显示地通过流的方式来操作应该会对程序的性能有一定的影响。在进行具体操作的时候要注意
相对路径和绝对路径的区别,如果获得了应用程序的作用域中的相对路径,可以通过File.getAbsolutePath()的方法来获取完整的绝对路径来进行操作。