Сжатие изображения камеры перед загрузкой
Я использую этот код (от www.internetria.com), чтобы сделать фотографию и загрузить на сервер:
OnCreate:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri output = Uri.fromFile(new File(foto));
intent.putExtra(MediaStore.EXTRA_OUTPUT, output);
startActivityForResult(intent, TAKE_PICTURE);
onActivityResult:
ImageView iv = (ImageView) findViewById(R.id.imageView1);
iv.setImageBitmap(BitmapFactory.decodeFile(foto));
File file = new File(foto);
if (file.exists()) {
UploaderFoto nuevaTarea = new UploaderFoto();
nuevaTarea.execute(foto);
}
else
Toast.makeText(getApplicationContext(), "No se ha realizado la foto", Toast.LENGTH_SHORT).show();
UploaderFoto:
ProgressDialog pDialog;
String miFoto = "";
@Override
protected Void doInBackground(String... params) {
miFoto = params[0];
try {
HttpClient httpclient = new DefaultHttpClient();
httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
HttpPost httppost = new HttpPost("http://servidor.com/up.php");
File file = new File(miFoto);
MultipartEntity mpEntity = new MultipartEntity();
ContentBody foto = new FileBody(file, "image/jpeg");
mpEntity.addPart("fotoUp", foto);
httppost.setEntity(mpEntity);
httpclient.execute(httppost);
httpclient.getConnectionManager().shutdown();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
И я хочу сжать изображение, потому что размер слишком большой.
Я не знаю, как добавить bitmap.compress(Bitmap.CompressFormat.JPEG, 70, fos);
в мое приложение
Ответы
Ответ 1
Взгляните сюда: ByteArrayOutputStream в FileBody
Что-то в этом направлении должно работать:
заменить
File file = new File(miFoto);
ContentBody foto = new FileBody(file, "image/jpeg");
с
Bitmap bmp = BitmapFactory.decodeFile(miFoto)
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(CompressFormat.JPEG, 70, bos);
InputStream in = new ByteArrayInputStream(bos.toByteArray());
ContentBody foto = new InputStreamBody(in, "image/jpeg", "filename");
Если размер файла по-прежнему является проблемой, вы можете захотеть масштабировать изображение в дополнение к его сжатию.
Ответ 2
Преобразовать изображение в Формат Google WebP, он сэкономит вам много байтов в следующих двух статьях, которые вы также можете преобразовать webP в JPG/PNG/GIF, что бы вы ни пожелали на стороне сервера.
Java Wrapper API Google WebP
Как проверить библиотеку Google WebP и использовать ее в Android как родную библиотеку
Во-первых, вам нужно получить пиксели из Bitmap.
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
int bytes = bitmap.getByteCount();
ByteBuffer buffer = ByteBuffer.allocate(bytes);
bitmap.copyPixelsToBuffer(buffer);
byte[] pixels = buffer.array();
Затем вы можете получить массив байтов WebP.
int stride = bytes / height;
int quality = 100;
byte[] encoded = libwebp.WebPEncodeRGBA(pixels, width, height, stride, quality);
Test.png(Размер: 106 КБ)
Test.webp(Размер: 48 КБ)
![Test.webp(Size: 48KB)]()
Ответ 3
Использование okhttp Я загружаю вот так:
MediaType MEDIA_TYPE_PNG
= MediaType.parse("image/jpeg");
//Compress Image
Bitmap bmp = BitmapFactory.decodeFile(fileToUpload.getAbsolutePath());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 70, bos);
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addFormDataPart("photo", fileToUpload.getName(), RequestBody.create(MEDIA_TYPE_PNG, bos.toByteArray()))
.build();
request = new Request.Builder()
.url(urlToUploadTo)
.post(requestBody)
.build();
try {
response = client.newCall(request).execute();
if (response != null) {
if (response.isSuccessful()) {
responseResult = response.body().string();
}
}
} catch (IOException e) {
e.printStackTrace();
}
Ответ 4
Посмотрите на метод compressImage()
:
public class MainActivity extends Activity {
private Uri fileUri;
private ImageView img_forCompress;
public static final int MEDIA_TYPE_IMAGE = 1;
private static final int CAMERA_REQUEST = 1888;
private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
private static final String IMAGE_DIRECTORY_NAME = "Ibook";
static File mediaFile;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
img_forCompress = (ImageView) findViewById(R.id.img_forCompress);
img_forCompress.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
startActivityForResult(intent,
CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}
});
}
public Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(type));
}
private static File getOutputMediaFile(int type) {
// External sdcard location
File mediaStorageDir = new File(
Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
IMAGE_DIRECTORY_NAME);
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create "
+ IMAGE_DIRECTORY_NAME + " directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
Locale.getDefault()).format(new Date());
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
} else {
return null;
}
Log.e("path", "media file:-" + mediaFile);
return mediaFile;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
Log.e("path", "" + mediaFile.toString());
String filename = mediaFile.toString();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(filename, options);
compressImage(bitmap);
}
private void compressImage(Bitmap photo) {
// TODO Auto-generated method stub
int imageWidth = photo.getWidth();
int imageHeight = photo.getHeight();
long length = mediaFile.length();
int newHeight = 0;
int newWidth = 0;
Toast.makeText(MainActivity.this, "oldwidth="+imageWidth+",oldHeight="+imageHeight,Toast.LENGTH_LONG).show();
Log.e("Old Image gheight and width---------", imageWidth + "-------"
+ imageHeight + " and Size is -- " + length);
if (imageHeight > 1500 || imageWidth > 1500) {
if (imageHeight > imageWidth) {
Log.e("height is more", "true");
newHeight = 1200;
newWidth = (newHeight * imageWidth / imageHeight);
}
if (imageWidth > imageHeight) {
Log.e("width is more", "true");
newWidth = 1200;
newHeight = (newWidth * imageHeight / imageWidth);
}
}
Toast.makeText(MainActivity.this, "newwidth="+newWidth+",newHeight="+newHeight,Toast.LENGTH_LONG).show();
Log.e("new Image gheight and width---------", newHeight + "-------"