Android调用相机拍照,压缩图片后保存SD卡中

2024-02-17 04:18

本文主要是介绍Android调用相机拍照,压缩图片后保存SD卡中,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近在搞一个项目,需求是调用系统相机拍完照片后保存本地,再上传至后台服务器,但为了节省流量需要压缩上传,将图片压缩至100K以内。这个是在特定机器上运行,类似于手持POS机,但是它的相机几乎没有优化,对焦慢,而且拍照也不清晰,使用自己的手机调用系统相机拍照后图片大概有300K左右,自动已经压缩了,但这个机器没有优化,调用相机拍照后的图片和原图一样2M左右,太大了,必须要压缩!
网上找了些资料,也作为参考:Android图片压缩 质量压缩和尺寸压缩;安卓相机拍摄照片,压缩后存储于SD卡
项目需要的效果为:

上代码:

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;public class MainActivity extends Activity implements OnClickListener{private Button openCamera,openCamera2;private ImageView showImgView;Uri photoUri;String filePath;  //图片路径@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findView();}private void findView() {// TODO Auto-generated method stubopenCamera = (Button) findViewById(R.id.openCamera);openCamera2 = (Button) findViewById(R.id.openCamera2);showImgView = (ImageView) findViewById(R.id.showImgView);openCamera.setOnClickListener(this);openCamera2.setOnClickListener(this);}@Overridepublic void onClick(View v) {// TODO Auto-generated method stubswitch (v.getId()){case R.id.openCamera://打卡相机前先检测SD卡是否可以用if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){photoUri = patrUri("file1");startCamera(1001,photoUri);}else{Toast.makeText(MainActivity.this, "SD卡不可用", Toast.LENGTH_SHORT).show();}break;case R.id.openCamera2:if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){photoUri = patrUri("file2");startCamera(1002,photoUri);}else{Toast.makeText(MainActivity.this, "SD卡不可用", Toast.LENGTH_SHORT).show();}break;}}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {// TODO Auto-generated method stubsuper.onActivityResult(requestCode, resultCode, data);if(requestCode == 1001){if(resultCode == RESULT_OK){FileInputStream is = null;try {is = new FileInputStream(filePath);Bitmap bitmap = BitmapFactory.decodeStream(is);showImgView.setImageBitmap(bitmap);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{try {is.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}if(requestCode == 1002){if(resultCode == RESULT_OK){try {Bitmap bitmap = compressBySize(filePath,480,800);  //设置压缩后图片的高度和宽度saveFile(bitmap,filePath);showImgView.setImageBitmap(bitmap);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}// 压缩图片尺寸private static Bitmap compressBySize(String pathName, int targetWidth,int targetHeight) {BitmapFactory.Options opts = new BitmapFactory.Options();opts.inJustDecodeBounds = true;// 不去真的解析图片,只是获取图片的头部信息,包含宽高等;Bitmap bitmap = BitmapFactory.decodeFile(pathName, opts);// 得到图片的宽度、高度;float imgWidth = opts.outWidth;float imgHeight = opts.outHeight;// 分别计算图片宽度、高度与目标宽度、高度的比例;取大于等于该比例的最小整数;int widthRatio = (int) Math.ceil(imgWidth / (float) targetWidth);int heightRatio = (int) Math.ceil(imgHeight / (float) targetHeight);opts.inSampleSize = 1;if (widthRatio > 1 || widthRatio > 1) {if (widthRatio > heightRatio) {opts.inSampleSize = widthRatio;} else {opts.inSampleSize = heightRatio;}}// 设置好缩放比例后,加载图片进内容;opts.inJustDecodeBounds = false;bitmap = BitmapFactory.decodeFile(pathName, opts);return bitmap;}//保存压缩后的图片private void saveFile(Bitmap bitmap, String filePath2) throws IOException {// TODO Auto-generated method stubFile testFile = new File(filePath2);if (testFile.exists()) {testFile.delete();}File myCaptureFile = new File(filePath2);System.out.println("------filePath2==" + filePath2);BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));// 100表示不进行压缩,70表示压缩率为30%bitmap.compress(Bitmap.CompressFormat.JPEG, 90, bos);bos.flush();bos.close();}//打开相机private void startCamera(int requestCode, Uri photoUri) {// TODO Auto-generated method stubIntent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);intent.putExtra(MediaStore.EXTRA_OUTPUT,photoUri);startActivityForResult(intent, requestCode);}/*** 图片保存路径  这里是在SD卡目录下创建了MyPhoto文件夹* @param fileName* @return*/private Uri patrUri(String fileName) {  //指定了图片的名字,可以使用时间来命名// TODO Auto-generated method stubString strPhotoName = fileName+".jpg";              String savePath = Environment.getExternalStorageDirectory().getPath()+ "/MyPhoto/";File dir = new File(savePath);if (!dir.exists()) {dir.mkdirs();}filePath = savePath + strPhotoName;return Uri.fromFile(new File(dir, strPhotoName));}
}

页面布局很简单,就两个Button跟一个ImageView,这里就不贴代码了。
效果图片:
这里写图片描述
SD卡中的图片:
这里写图片描述
可以看到,file2.jpg是压缩过的,file1.jpg是原图,因为是模拟器,效果不太明显,在真机上压缩后的图片在100K之内。

要调用相机和读写SD卡,最后不要忘了加权限。

代码下载
因为工作的原因,这里使用的是Myeclipse不过Eclipse也可以用。

这篇关于Android调用相机拍照,压缩图片后保存SD卡中的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/716652

相关文章

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

hdu1565(状态压缩)

本人第一道ac的状态压缩dp,这题的数据非常水,很容易过 题意:在n*n的矩阵中选数字使得不存在任意两个数字相邻,求最大值 解题思路: 一、因为在1<<20中有很多状态是无效的,所以第一步是选择有效状态,存到cnt[]数组中 二、dp[i][j]表示到第i行的状态cnt[j]所能得到的最大值,状态转移方程dp[i][j] = max(dp[i][j],dp[i-1][k]) ,其中k满足c

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(五):Blender锥桶建模

前言 本系列教程旨在使用UE5配置一个具备激光雷达+深度摄像机的仿真小车,并使用通过跨平台的方式进行ROS2和UE5仿真的通讯,达到小车自主导航的目的。本教程默认有ROS2导航及其gazebo仿真相关方面基础,Nav2相关的学习教程可以参考本人的其他博客Nav2代价地图实现和原理–Nav2源码解读之CostMap2D(上)-CSDN博客往期教程: 第一期:基于UE5和ROS2的激光雷达+深度RG

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk