package com.ninetowns.common;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.util.Calendar;
import org.json.JSONArray;
import org.json.JSONObject;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore.MediaColumns;
import android.util.Log;
import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
public class ImgPlugin extends Plugin {
private Object synObj = new Object();
public static String ACTION_PHOTO = "photo"; // 拍照
public static String ACTION_GETPICTURE = "picture"; // 相机选择
public static String ACTION_IMGTOBASE64 = "base64"; // 转Base64
private static final int PHOTO_REQUEST_CUT = 3;// 结果
public String callback;
@Override
public PluginResult execute(final String action, final JSONArray data,
final String callBackId) {
this.callback = callBackId;
PluginResult pluginResult = null;
Log.i("ImgPlugin", "ImgPlugin called");
if (ACTION_PHOTO.equals(action)) {
Log.i("Urlurlurlurl", data.optString(0));
Uri u = Uri.parse(data.optString(0));
Log.i("Url", data.optString(0));
crop(u);
} else if (ACTION_GETPICTURE.equals(action)) {
// 拍照
} else if (ACTION_IMGTOBASE64.equals(action)) {
ImgToBase64(data);
} else {
return new PluginResult(PluginResult.Status.INVALID_ACTION);
}
PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
r.setKeepCallback(true);
return r;
}
private PluginResult ImgToBase64(JSONArray data) {
PluginResult result = null;
try {
JSONObject defaultdate = new JSONObject(data.getString(0));
Log.i("ImgPlugin", "ImgUrl:" + defaultdate.getString("isall"));
String oldUrl = defaultdate.getString("isall");
String srtemp = moveFile(oldUrl);
// 位图保存
File imageFile = savePhoto(getimage(srtemp));
Uri contentUri = Uri.fromFile(imageFile);
Log.i("ImgPlugin", "ImgUrlxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:" + contentUri);
String ulo = "";
Log.i("xxxxxxxxxxxxxxxxxx", ulo);
JSONObject res = new JSONObject();
res.put("success", true);
// res.put("ImageData", Tool.GetImageStr(srtemp));
result = new PluginResult(PluginResult.Status.OK, res);
} catch (Exception e) {
Log.e("DataPlugin", e.getMessage());
result = new PluginResult(PluginResult.Status.ERROR, e.getMessage());
}
return result;
}
/**
* 图片按比例大小压缩方法
*
* @param srcPath
* (根据路径获取图片并压缩)
* @return
*/
public static Bitmap getimage(String srcPath) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
float hh = 480f;
float ww = 480f;
int be = 1;
if (w > h && w > ww) {
be = (int) (newOpts.outWidth / ww);
} else if (w < h && h > hh) {
be = (int) (newOpts.outHeight / hh);
}
if (be <= 0)
{
be = 1;
}
Log.i("xxxxxxxxxxxxxxxxxxxxxxxxxx", "inSampleSize:"+be);
newOpts.inSampleSize = be;
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
//return compressImage(bitmap);
return bitmap;
}
/**
* 质量压缩方法
*
* @param image
* @return
*/
public static Bitmap compressImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
int options = 90;
while ((baos.toByteArray().length / 1024) > 50) {
baos.reset();
image.compress(Bitmap.CompressFormat.JPEG, options, baos);
options -= 10;
Log.i("xxxxxxxxxxxxxxxxxxxxxxxxxx", "options:"+options);
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
return bitmap;
}
public String moveFile(String oldurl) {
try {
String newPath = "";
String newName = "";
if (oldurl.contains("file://")) {
newName = oldurl.replace("file://", "");
}
if (oldurl.contains("content://")) {
newName = getLocalPath(oldurl);
}
String dbdisk = Environment.getExternalStorageDirectory()
+ "/ninetowns_img/";
try {
File file = new File(oldurl);
if (file.isFile() && file.exists()) {
file.delete();
}
InputStream assetsDB = new FileInputStream(newName);
Tool.makeRootDirectory(dbdisk);
newName = Tool.getFileNameToUrl(newName);
Log.i("ImgPlugin", "MoveImgToNewPath3:" + newName);
OutputStream dbOut = new FileOutputStream(dbdisk + newName);
Log.i("ImgPlugin", "MoveImgToNewPath4:" + newName);
byte[] buffer = new byte[1024];
int length;
while ((length = assetsDB.read(buffer)) > 0) {
dbOut.write(buffer, 0, length);
}
dbOut.flush();
dbOut.close();
assetsDB.close();
Intent intent = new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri uri = Uri.fromFile(new File(dbdisk + newName));// Uri.parse(dbdisk+newName);//
// Uri.fromFile(dbdisk+newName);
Log.i("ImgPlugin", "MoveImgToNewPath5:" + uri.getPath());
newPath = uri.getPath();
intent.setData(uri);
this.ctx.getContext().sendBroadcast(intent);
} catch (Exception e) {
Log.e("PGSQLitePlugin",
"error get db from assets=" + e.getMessage());
}
return newPath;
} catch (Exception e) {
Log.e("ImgPlugin", e.getMessage());
return "";
}
}
private String getLocalPath(String myImageUrl) {
String temp = "";
try {
Uri uri = Uri.parse(myImageUrl);
String[] proj = { MediaColumns.DATA };
Cursor actualimagecursor = this.ctx.getContext()
.getContentResolver().query(uri, proj, null, null, null);
int actual_image_column_index = actualimagecursor
.getColumnIndexOrThrow(MediaColumns.DATA);
actualimagecursor.moveToFirst();
temp = actualimagecursor.getString(actual_image_column_index);
} catch (Exception e) {
Log.e("ImgPlugin getLocalPath", e.getMessage());
}
return temp;
}
/*
* 剪切图片
*/
private void crop(Uri uri) {
// 裁剪图片意图
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
// 裁剪框的比例,1:1
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// 裁剪后输出图片的尺寸大小
intent.putExtra("outputX", 250);
intent.putExtra("outputY", 250);
intent.putExtra("outputFormat", "JPEG");// 图片格式
intent.putExtra("noFaceDetection", true);// 取消人脸识别
intent.putExtra("return-data", true);
Log.d("crop", "xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
// 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CUT
ctx.startActivityForResult(ImgPlugin.this, intent, PHOTO_REQUEST_CUT);
Log.d("crop", "fffffffffffffffffff");
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data != null) {
Bitmap bitmap = data.getParcelableExtra("data");
// 位图保存
File imageFile = savePhoto(bitmap);
Uri contentUri = Uri.fromFile(imageFile);
this.success(new PluginResult(PluginResult.Status.OK, ""
+ contentUri), this.callback);
} else {
this.error(new PluginResult(PluginResult.Status.ERROR),
this.callback);
}
}
private File savePhoto(Bitmap bmp) {
File retVal = null;
try {
Calendar c = Calendar.getInstance();
String date = "" + c.get(Calendar.DAY_OF_MONTH)
+ c.get(Calendar.MONTH) + c.get(Calendar.YEAR)
+ c.get(Calendar.HOUR_OF_DAY) + c.get(Calendar.MINUTE)
+ c.get(Calendar.SECOND);
String deviceVersion = Build.VERSION.RELEASE;
Log.i("Canvas2ImagePlugin", "Android version " + deviceVersion);
int check = deviceVersion.compareTo("2.3.3");
File folder;
/*
* File path = Environment.getExternalStoragePublicDirectory(
* Environment.DIRECTORY_PICTURES ); //this throws error in Android
* 2.2
*/
if (check >= 1) {
folder = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
if (!folder.exists()) {
folder.mkdirs();
}
} else {
folder = Environment.getExternalStorageDirectory();
}
File imageFile = new File(folder, "c2i_" + date.toString() + ".png");
FileOutputStream out = new FileOutputStream(imageFile);
bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
retVal = imageFile;
} catch (Exception e) {
Log.e("Canvas2ImagePlugin",
"An exception occured while saving image: " + e.toString());
}
return retVal;
}
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.util.Calendar;
import org.json.JSONArray;
import org.json.JSONObject;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore.MediaColumns;
import android.util.Log;
import org.apache.cordova.api.Plugin;
import org.apache.cordova.api.PluginResult;
public class ImgPlugin extends Plugin {
private Object synObj = new Object();
public static String ACTION_PHOTO = "photo"; // 拍照
public static String ACTION_GETPICTURE = "picture"; // 相机选择
public static String ACTION_IMGTOBASE64 = "base64"; // 转Base64
private static final int PHOTO_REQUEST_CUT = 3;// 结果
public String callback;
@Override
public PluginResult execute(final String action, final JSONArray data,
final String callBackId) {
this.callback = callBackId;
PluginResult pluginResult = null;
Log.i("ImgPlugin", "ImgPlugin called");
if (ACTION_PHOTO.equals(action)) {
Log.i("Urlurlurlurl", data.optString(0));
Uri u = Uri.parse(data.optString(0));
Log.i("Url", data.optString(0));
crop(u);
} else if (ACTION_GETPICTURE.equals(action)) {
// 拍照
} else if (ACTION_IMGTOBASE64.equals(action)) {
ImgToBase64(data);
} else {
return new PluginResult(PluginResult.Status.INVALID_ACTION);
}
PluginResult r = new PluginResult(PluginResult.Status.NO_RESULT);
r.setKeepCallback(true);
return r;
}
private PluginResult ImgToBase64(JSONArray data) {
PluginResult result = null;
try {
JSONObject defaultdate = new JSONObject(data.getString(0));
Log.i("ImgPlugin", "ImgUrl:" + defaultdate.getString("isall"));
String oldUrl = defaultdate.getString("isall");
String srtemp = moveFile(oldUrl);
// 位图保存
File imageFile = savePhoto(getimage(srtemp));
Uri contentUri = Uri.fromFile(imageFile);
Log.i("ImgPlugin", "ImgUrlxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:" + contentUri);
String ulo = "";
Log.i("xxxxxxxxxxxxxxxxxx", ulo);
JSONObject res = new JSONObject();
res.put("success", true);
// res.put("ImageData", Tool.GetImageStr(srtemp));
result = new PluginResult(PluginResult.Status.OK, res);
} catch (Exception e) {
Log.e("DataPlugin", e.getMessage());
result = new PluginResult(PluginResult.Status.ERROR, e.getMessage());
}
return result;
}
/**
* 图片按比例大小压缩方法
*
* @param srcPath
* (根据路径获取图片并压缩)
* @return
*/
public static Bitmap getimage(String srcPath) {
BitmapFactory.Options newOpts = new BitmapFactory.Options();
newOpts.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
newOpts.inJustDecodeBounds = false;
int w = newOpts.outWidth;
int h = newOpts.outHeight;
float hh = 480f;
float ww = 480f;
int be = 1;
if (w > h && w > ww) {
be = (int) (newOpts.outWidth / ww);
} else if (w < h && h > hh) {
be = (int) (newOpts.outHeight / hh);
}
if (be <= 0)
{
be = 1;
}
Log.i("xxxxxxxxxxxxxxxxxxxxxxxxxx", "inSampleSize:"+be);
newOpts.inSampleSize = be;
bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
//return compressImage(bitmap);
return bitmap;
}
/**
* 质量压缩方法
*
* @param image
* @return
*/
public static Bitmap compressImage(Bitmap image) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, baos);
int options = 90;
while ((baos.toByteArray().length / 1024) > 50) {
baos.reset();
image.compress(Bitmap.CompressFormat.JPEG, options, baos);
options -= 10;
Log.i("xxxxxxxxxxxxxxxxxxxxxxxxxx", "options:"+options);
}
ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);
return bitmap;
}
public String moveFile(String oldurl) {
try {
String newPath = "";
String newName = "";
if (oldurl.contains("file://")) {
newName = oldurl.replace("file://", "");
}
if (oldurl.contains("content://")) {
newName = getLocalPath(oldurl);
}
String dbdisk = Environment.getExternalStorageDirectory()
+ "/ninetowns_img/";
try {
File file = new File(oldurl);
if (file.isFile() && file.exists()) {
file.delete();
}
InputStream assetsDB = new FileInputStream(newName);
Tool.makeRootDirectory(dbdisk);
newName = Tool.getFileNameToUrl(newName);
Log.i("ImgPlugin", "MoveImgToNewPath3:" + newName);
OutputStream dbOut = new FileOutputStream(dbdisk + newName);
Log.i("ImgPlugin", "MoveImgToNewPath4:" + newName);
byte[] buffer = new byte[1024];
int length;
while ((length = assetsDB.read(buffer)) > 0) {
dbOut.write(buffer, 0, length);
}
dbOut.flush();
dbOut.close();
assetsDB.close();
Intent intent = new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri uri = Uri.fromFile(new File(dbdisk + newName));// Uri.parse(dbdisk+newName);//
// Uri.fromFile(dbdisk+newName);
Log.i("ImgPlugin", "MoveImgToNewPath5:" + uri.getPath());
newPath = uri.getPath();
intent.setData(uri);
this.ctx.getContext().sendBroadcast(intent);
} catch (Exception e) {
Log.e("PGSQLitePlugin",
"error get db from assets=" + e.getMessage());
}
return newPath;
} catch (Exception e) {
Log.e("ImgPlugin", e.getMessage());
return "";
}
}
private String getLocalPath(String myImageUrl) {
String temp = "";
try {
Uri uri = Uri.parse(myImageUrl);
String[] proj = { MediaColumns.DATA };
Cursor actualimagecursor = this.ctx.getContext()
.getContentResolver().query(uri, proj, null, null, null);
int actual_image_column_index = actualimagecursor
.getColumnIndexOrThrow(MediaColumns.DATA);
actualimagecursor.moveToFirst();
temp = actualimagecursor.getString(actual_image_column_index);
} catch (Exception e) {
Log.e("ImgPlugin getLocalPath", e.getMessage());
}
return temp;
}
/*
* 剪切图片
*/
private void crop(Uri uri) {
// 裁剪图片意图
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");
// 裁剪框的比例,1:1
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// 裁剪后输出图片的尺寸大小
intent.putExtra("outputX", 250);
intent.putExtra("outputY", 250);
intent.putExtra("outputFormat", "JPEG");// 图片格式
intent.putExtra("noFaceDetection", true);// 取消人脸识别
intent.putExtra("return-data", true);
Log.d("crop", "xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
// 开启一个带有返回值的Activity,请求码为PHOTO_REQUEST_CUT
ctx.startActivityForResult(ImgPlugin.this, intent, PHOTO_REQUEST_CUT);
Log.d("crop", "fffffffffffffffffff");
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data != null) {
Bitmap bitmap = data.getParcelableExtra("data");
// 位图保存
File imageFile = savePhoto(bitmap);
Uri contentUri = Uri.fromFile(imageFile);
this.success(new PluginResult(PluginResult.Status.OK, ""
+ contentUri), this.callback);
} else {
this.error(new PluginResult(PluginResult.Status.ERROR),
this.callback);
}
}
private File savePhoto(Bitmap bmp) {
File retVal = null;
try {
Calendar c = Calendar.getInstance();
String date = "" + c.get(Calendar.DAY_OF_MONTH)
+ c.get(Calendar.MONTH) + c.get(Calendar.YEAR)
+ c.get(Calendar.HOUR_OF_DAY) + c.get(Calendar.MINUTE)
+ c.get(Calendar.SECOND);
String deviceVersion = Build.VERSION.RELEASE;
Log.i("Canvas2ImagePlugin", "Android version " + deviceVersion);
int check = deviceVersion.compareTo("2.3.3");
File folder;
/*
* File path = Environment.getExternalStoragePublicDirectory(
* Environment.DIRECTORY_PICTURES ); //this throws error in Android
* 2.2
*/
if (check >= 1) {
folder = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
if (!folder.exists()) {
folder.mkdirs();
}
} else {
folder = Environment.getExternalStorageDirectory();
}
File imageFile = new File(folder, "c2i_" + date.toString() + ".png");
FileOutputStream out = new FileOutputStream(imageFile);
bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
retVal = imageFile;
} catch (Exception e) {
Log.e("Canvas2ImagePlugin",
"An exception occured while saving image: " + e.toString());
}
return retVal;
}
}
备注:
照片压缩, 三种方式 1、比例压缩 2、照片质量压缩 3、写入流存储格式;
最近项目中需要用到照片压缩,之前的几次压缩效果, 都不近人意,最后发现是照片写入文件流的时候, 犯错了 ,
bmp.compress(Bitmap.CompressFormat.PNG, 100, out); 把其中Bitmap.CompressFormat.PNG 改成 google公司的 Bitmap.CompressFormat.WEBP,图片就有上百倍的压缩效果,而且图片质量也能有保障, 查阅相关资料, 说微信目前也是采用这种技术;