拍照并保存文件的小例子

需求:一个Android的地图应用,当在地图上点击某一建筑物(例如:逸夫楼)时将进入该建筑物的详情界面,此界面有一个按钮拍照,点击后启动系统自带的拍照功能,拍照后将图片保存在某一固定文件夹下,同一建筑物的图片文件名只有文件名末尾的数字不同。例如我之前已经在建筑物“逸夫楼”拍了两张图片,则命名分别为:“逸夫楼1”,““逸夫楼2””。那么之后我再拍逸夫楼的照片则命名为“逸夫楼3”.详情界面会显示该建筑物的所有图片。部分代码如下:

<!--布局文件相关控件--> 

<Button
	android:id="@+id/takePhotoBtn"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:text="拍照" />

<Gallery
	android:id="@+id/viewGallery"
	android:layout_width="200dip"
	android:layout_height="200dip"
	android:layout_weight="1" />

viewGallery.setAdapter(new ImageAdapter(SpotDetail2Activity.this,"/sdcard/VMapImage",spotInfo.get("Display")));
//spotInfo.get("Display"):获得当前建筑物的名称
takePhotoBtn.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
				 startActivityForResult(intent, 1);
			}
		});


 
 
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	// TODO Auto-generated method stub
	super.onActivityResult(requestCode, resultCode, data);
	if (resultCode == Activity.RESULT_OK) {
    	   //返回外部存储卡(SD)的状态
           String sdStatus = Environment.getExternalStorageState();
           if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd是否可用
               Log.v("TestFile",
                       "SD card is not avaiable/writeable right now.");
               return;
           }

           Bundle bundle = data.getExtras();
           Bitmap bitmap = (Bitmap) bundle.get("data");// 获取相机返回的数据,并转换为Bitmap图片格式
           FileOutputStream b = null; 
           String dir="/sdcard/VMapImage/";
           File file = new File(dir);
           if(file.exists()==false)
        	   file.mkdirs();
           dir=dir+spotInfo.get("Display");  //获得当前建筑物的名称
           String fileName=dir;
           int i=0;
           while(true)
           {
        	   i++;
        	   fileName=dir+i+".jpg";
        	   file = new File(fileName);
        	   try {
				if(file.exists()==false)
				{
					file.createNewFile();
					break;
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				Log.v("TestFile",
	                       "create file" +fileName+"failed!");
				e.printStackTrace();
			}
           }
           try {
               b = new FileOutputStream(fileName);
               bitmap.compress(Bitmap.CompressFormat.JPEG, 100, b);// 把数据写入文件
           } catch (FileNotFoundException e) {
               e.printStackTrace();
           } finally {
               try {
                   b.flush();
                   b.close();
               } catch (IOException e) {
                   e.printStackTrace();
               }
           }
	}
}

public class ImageAdapter extends BaseAdapter {
	private Context mContext=null;
	public String picpath=null;
	private String[] myImageNames=null;
	public String positionName=null;
	public ImageAdapter(Context c, String path,String position) {

		mContext = c;
		picpath = path;
        this.positionName=position;
		myImageNames =getImageNames(picpath,position);

	}
	//获取某一目录下以某一名称开头的图片
	public static String[] getImageNames(String folderPath,String positionName) {
		File file01 = new File(folderPath);
 
		int imageFileNums=0;
		String[] files01 = file01.list();
        ArrayList<String> nameList=new ArrayList<String>();
		for (int i = 0; i < files01.length; i++) {
			File file02 = new File(folderPath + "/" + files01[i]);
			if (!file02.isDirectory()) {
				if (isMyImageFile(file02.getName(),positionName)) {
					imageFileNums++;
					nameList.add(file02.getName());
				}
			}
		}
		
       // return (String[])nameList.toArray();
	String[] files02 = new String[imageFileNums];

		int j = 0;
		for (int i = 0; i < files01.length; i++) {
			File file02 = new File(folderPath + "/" + files01[i]);

			if (!file02.isDirectory()) {

				if (isMyImageFile(file02.getName(),positionName)) {
					files02[j] = file02.getName();
					j++;
				}
			}
		}
		return files02;
	}

	private static boolean isMyImageFile(String fileName,String pre) {
		
		String fileStart=fileName.substring(0, pre.length());
		if(false==fileStart.equalsIgnoreCase(pre))
			return false;
		
		String fileEnd = fileName.substring(fileName.lastIndexOf(".") + 1,
				fileName.length());
		
		if (fileEnd.equalsIgnoreCase("jpg")) {
			return true;
		} else if (fileEnd.equalsIgnoreCase("png")) {
			return true;
		} else if (fileEnd.equalsIgnoreCase("bmp")) {
			return true;
		} else {
			return false;
		}
	}
	
	
	
	public int getCount() {

		return myImageNames.length;
	}

	@Override
	public Object getItem(int position) {
		// TODO Auto-generated method stub
		return position;
	}

	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return position;
	}

	public View getView(int position, View convertView, ViewGroup parent) {

		ImageView imageView = new ImageView(mContext);
		imageView.setImageURI(Uri.parse(picpath + "/" + myImageNames[position]));
		imageView.setLayoutParams(new Gallery.LayoutParams(200, 200));
		imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
		return imageView;
	}
}


 
上面的保存的图片的方法存在的问题是图片不清晰。主要原因是图片使压缩存储的,自然就不清楚了。下面用另一种方法将,此方法保存的图片和与手机拍照的照片原形清晰度是一样的。关键代码如下:
 
public void onClick(View arg0) {
				// TODO Auto-generated method stub
				 
				 Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
				 String filePathString=generateNewImageFileName();
				 Uri mUri = Uri.fromFile(new File(filePathString));
				 cameraIntent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, mUri);
				 try {
						cameraIntent.putExtra("return-data", true);
						startActivityForResult(cameraIntent, 1);
					} catch (Exception e) {
						e.printStackTrace();
					}
			}

protected String generateNewImageFileName()
	{
		String imagesDir=Environment.getExternalStorageDirectory()
				+ "/VMapImage";
		File fileDir = new File(imagesDir);
		if (!fileDir.exists()) {
			fileDir.mkdir();
		}
		imagesDir=imagesDir+"/";
	String filePath="";
	int i=0;
	while(true)
	{
		   i++;
		   filePath=imagesDir+spotInfo.get("Display")+i+".jpg";
		   File file = new File(filePath);
		   if(file.exists()==false)
			   break;
	}
	 return filePath;
}
 
 
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	// TODO Auto-generated method stub
	super.onActivityResult(requestCode, resultCode, data);
	if (resultCode == Activity.RESULT_OK) {
    	   //返回外部存储卡(SD)的状态
           String sdStatus = Environment.getExternalStorageState();
           if (!sdStatus.equals(Environment.MEDIA_MOUNTED)) { // 检测sd是否可用
               Log.v("TestFile",
                       "SD card is not avaiable/writeable right now.");
               return;
           }
           imageAdapter=new ImageAdapter(SpotDetail2Activity.this,Environment.getExternalStorageDirectory()
   				+ "/VMapImage",spotInfo.get("Display"));
		   gallery.setAdapter(imageAdapter);
	}
}

 
 
 
 
 
之后又发现一个问题:因为Gallery中显示的图片是直接获取的拍照图片。当手机像素较高时会出现内存溢出的情况。解决方法是Gallery中显示缩略图。只需将上面代码中ImageAdapter中的getView方法改写一下:
public View getView(int position, View convertView, ViewGroup parent) {
		ImageView imageView = new ImageView(mContext);
		imageView.setImageBitmap(getBitmap(picpath + "/" + myImageNames[position]));
		imageView.setLayoutParams(new Gallery.LayoutParams(200, 200));
		imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
		return imageView;
	}
	public Bitmap getBitmap(String path)
	{
		 BitmapFactory.Options option = new BitmapFactory.Options();
		 option.inJustDecodeBounds = true;
		 Bitmap bitmap = BitmapFactory.decodeFile(path,option);
		 option.inSampleSize = option.outWidth/100; 
		 option.inJustDecodeBounds = false;
		 option.inPreferredConfig = Bitmap.Config.ARGB_8888;
		 option.inPurgeable = true;
		 option.inInputShareable = true;
		 try {
		 bitmap = BitmapFactory.decodeFile(path,option);
		 } catch (OutOfMemoryError e) {
		 e.printStackTrace();
		 } 
		 return bitmap;
	}




 


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值