【问题标题】:Compress camera image before upload上传前压缩相机图像
【发布时间】:2013-11-04 19:49:43
【问题描述】:

我正在使用此代码(来自www.internetria.com)拍照并上传到服务器:

创建:

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();

上传者照片:

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); 添加到我的应用中

【问题讨论】:

标签: android image upload camera compression


【解决方案1】:

请看这里:ByteArrayOutputStream to a 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");

如果文件大小仍然是个问题,除了压缩图片之外,您可能还需要缩放图片。

【讨论】:

  • InputStreamBody 已弃用。现在呢?
  • ContentBody foto = new ByteArrayBody(bos.toByteArray(), filename);
  • 这可能会使大图像中的 OutOfMemory 异常。您可以使用它来避免任何问题:developer.android.com/topic/performance/graphics/load-bitmap
  • 我也在使用 Bitmap 的压缩功能,但我的问题是我的图片在压缩后看起来很奇怪。也许是因为我没有使用 ByteArrayOutpuStream?我正在使用普通的输出流
【解决方案2】:

将图像转换为Google WebP format 可以节省大量字节,请参阅以下两篇文章,您还可以在服务器端将 webP 转换为 JPG/PNG/GIF。

Java Wrapper of Google WebP API

How to check out Google WebP library and use it in Android as native library

首先,您需要从 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(大小:106KB) Test.webp(大小: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 + "-------"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-01
      • 2021-10-06
      • 1970-01-01
      • 2021-01-03
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多