需求: 昨天客户发来需求说app里面图片不清晰,需要修改图片清晰度。
原因: 之前的代码由于app的图片要上传到图片服务器,为了节省流量和减少上传时的耗时,所以图片应该尽量小,但却导致了图片不清晰。
解决思路:好吧,问题来了,如何找一个让客户满意,图片大小和清晰度合适的参数呢?
我想了下,写了个测试工具给客户,让客户自己选择,希望这个工具对大家都有用。
图片压缩,可以看做是分辨率和压缩率的结合;
具体操作,先设置分辨率大小,压缩率大小,建议压缩率30 不失真,拍照获取图片,可以通过具体设置的路径,查看原始图片和压缩过的图片大小和清晰度。
public class MainActivity extends Activity implements OnItemClickListener{
private Gallery gallery;
private EditText width,height,compression_ratio;
private String fileDirStr;
private String imageFile;
private String createTime;
private Button bt_pic;
private List attaches = new ArrayList();
/**
* 返回小图片的设备列表
*/
private static List CAPTURE_SMALL_SIZE_IMAGE_DEVICES;
private static final int IMAGE_CAPTURE = 0;
static {
CAPTURE_SMALL_SIZE_IMAGE_DEVICES = new ArrayList();
}
private static final String TMP_IMAGE = "tmp.jpg";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
width = (EditText) findViewById(R.id.width);
height = (EditText) findViewById(R.id.height);
compression_ratio = (EditText) findViewById(R.id.compression_ratio);
bt_pic = (Button) findViewById(R.id.bt_pic);
bt_pic.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(!TextUtils.isEmpty(width.getText()) && !TextUtils.isEmpty(height.getText())
&& !TextUtils.isEmpty(compression_ratio.getText())){
captureImage(MainActivity.this, IMAGE_CAPTURE);//拍照
}else{
Toast.makeText(MainActivity.this, "请填参数", Toast.LENGTH_LONG).show();
}
}
});
gallery = (Gallery) findViewById(R.id.gallery);
gallery.setOnItemClickListener(this);
// 初始化附件目录(此目录查看压缩过后的图片)
fileDirStr =
Environment.getExternalStorageDirectory()+
getResources().getString(R.string.kdumpda_filepath)
+ "/" + getDateFormatForFile()
+ "/";
File fileDir = new File(fileDirStr);
if (!fileDir.exists()) {
fileDir.mkdirs();
}
}
/**
* 调用系统拍照功能拍照
*
* @param activity
* @param requestCode
* startActivityForResult的requestCode
*/
public void captureImage(Activity activity, int requestCode) {
Intent intent = new Intent(
android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
if (!shouldCaptureSmallImage()) {
File photo = new File(getTempDirectoryPath(activity), TMP_IMAGE);//临时存放的原始图片,按现在手机的分辨率,一般都有几M大小
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photo));
}
activity.startActivityForResult(intent, requestCode);
}
/**
* 获取临时存放文件夹路径
*
* @param ctx
* @return
*/
protected static String getTempDirectoryPath(Context ctx) {
File cache = null;
// 存放在外部存储(此目录查看原始图片)
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
cache = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath()
+ "/Android/data/"
+ ctx.getPackageName() + "/cache1/");
}
// 存放在内部存储
else {
cache = ctx.getCacheDir();
}
// 创建文件夹
if (!cache.exists()) {
cache.mkdirs();
}
return cache.getAbsolutePath();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == IMAGE_CAPTURE) {// 拍照
createTime = getDateFormatForFile();
imageFile = fileDirStr + createTime + ".jpg";
boolean result = handlePictureAndWatermarkForIntent(this, data,
imageFile, getCurrentTime()
+ " 来自寻觅的博客",
width.getText().toString().trim(),
height.getText().toString().trim());
if (result) {
addAttach(imageFile, AttachInfo.JPG_TYPE);
} else {
Toast.makeText(this, "获取图片失败,请重试!", Toast.LENGTH_LONG)
.show();
}
}
}
super.onActivityResult(requestCode, resultCode, data);
}
/**
* 获取图片并打水印
*
* @param activity
* @param data
* 包含图片信息的intent
* @param file
* 存储路径
* @param width
* 输出图片的宽
* @param height
* 输出图片的长
* @param mark
* 水印
* @return
*/
public boolean handlePictureAndWatermarkForIntent(Activity activity,
Intent data, String file, int width, int height, String mark) {
boolean result = false;
Bitmap bitmap = handlePictureForIntent(activity, data, width, height);
if (bitmap != null) {
bitmap = watermark(bitmap, mark);
try {
saveBitmap(file, bitmap,compression_ratio.getText().toString().trim());
result = true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bitmap != null) {
bitmap.recycle();
bitmap = null;
}
}
}
return result;
}
/**
* 获取系统拍照返回的图片
*
* @param activity
* @param data
* @param file
* @param width
* @param height
* @return
*/
public static Bitmap handlePictureForIntent(Activity activity, Intent data,
int width, int height) {
Bitmap bitmap = null;
if (shouldCaptureSmallImage()) {// 直接从返回值中获取
if (data != null && data.getExtras() != null
&& data.getExtras().getParcelable("data") != null) {
bitmap = data.getExtras().getParcelable("data");
if (bitmap != null && bitmap.getWidth() > bitmap.getHeight()) { // 旋转图片
bitmap = rotateBitmap(bitmap, 90);
}
bitmap = zoomBitmap(bitmap, width, height);
}
} else {// 从文件中获取bitmap,临时的原始图片(几M)
String tmpFile = getTempDirectoryPath(activity) + File.separator
+ TMP_IMAGE;
bitmap = handlePictureForFile(tmpFile, width, height);
}
return bitmap;
}
/**
* 处理文件图片
*
* @param file
* @param width
* 图片宽度
* @param height
* 图片高度
* @return
*/
public static Bitmap handlePictureForFile(String file, int width, int height) {
Bitmap bitmap = null;
final BitmapFactory.Options options = new BitmapFactory.Options();
// 只获取图片大小
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file, options);
// 获取bitmap
options.inJustDecodeBounds = false;
options.inSampleSize = Math.max(options.outWidth / width,
options.outHeight / height);
bitmap = BitmapFactory.decodeFile(file, options);
if (bitmap != null && bitmap.getWidth() > bitmap.getHeight()) { // 旋转图片
bitmap = rotateBitmap(bitmap, 90);
}
return zoomBitmap(bitmap, width, height);
}
/**
* 保存bitmap
*
* @param file
* @param bitmap
* @throws IOException
*/
public static void saveBitmap(String file, Bitmap bitmap,String compression_ratio)
throws IOException {
// 压缩图片并保存至文件
File photo = new File(file);
String dir = photo.getParent();
if (dir != null) {
new File(dir).mkdirs();
}
if (!photo.exists()) {
photo.createNewFile();
}
FileOutputStream outStream = new FileOutputStream(photo);
bitmap.compress(CompressFormat.JPEG,Integer.valueOf(compression_ratio), outStream);
outStream.flush();
outStream.close();
}
Environment.getExternalStorageDirectory()
.getAbsolutePath()
+ "/Android/data/"
+ ctx.getPackageName() + "/cache1/"
路径下的原始图片大小清晰度。
和查看
Environment.getExternalStorageDirectory()+
getResources().getString(R.string.kdumpda_filepath)
+ "/" + getDateFormatForFile()
+ "/"
压缩过后的图片大小和清晰度。
具体的实现过程,通过demo查看。
百度网盘的DEMO