3

After almost two weeks... I give up!!!

I achieve upload an image from gallery and camera...

startActivityForResult... ok!  
EXTERNAL_CONTENT_URI... ok!  
ACTION_IMAGE_CAPTURE... ok!  
onActivityResult... ok!  
Activity.RESULT_OK ('cause I'm on Fragment)... ok!  
getActivity().getContentResolver().query()... ok!  
BitmapFactory.Options, opts.inSampleSize, .decodeFile... ok!  

but I can't reduce the size of image to 900px, before upload to server using...

- FileInputStream(sourceFile);  
- HttpURLConnection  
- DataOutputStream( getOutputStream)  
- dos.writeBytes(form... name... file name...)
- dos.write(buffer, 0, bufferSize) 

I can't understand...
- How use "createScaledBitmap" in this case.
- How can I use "writeBytes(...filename=?)" if when I create a new bitmap, it doesn't have a path (at least I think so).
- If I have an original image on disk, what it's the path of result of "createScaledBitmap"?
- How buffer work (Step by Step would be great), and why in others examples on stackoverflow don't use it?

I have read many references including:
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
But I already used "options.inSampleSize" for make a Preview on my Fragment, and I think I need (in my case) "createScaledBitmap" for achieve my 900x900px image for upload.

If there is another way to upload images with resize include... let me know!
(Any links would be helpful)

I know... I should use AsyncTask... I'm working on that! ;)

Please consider not talk so technical because I have the worst combination for learning Android: newbie and speak spanish! xD

ADDED:
Anybody can help with the thing that @GVSharma says here?
Upload compressed image

"you got string path first na.so convert it to bitmap and compress it. instead of sending string file path as first argument to that method change that first argument to Bitmap bitmap. or you need String file path only then again convert the compressed bitmap to String. hope this one could help you"
(I have no idea how to do this)

public int uploadFile(String sourceFileUri) {

    final String fileName = sourceFileUri;

    HttpURLConnection conn = null;
    DataOutputStream dos = null; 
    String lineEnd = "\r\n";
    String twoHyphens = "--";
    String boundary = "*****";
    int bytesRead, bytesAvailable, bufferSize;
    byte[] buffer;
    int maxBufferSize = 1 * 1024 * 1024;
    File sourceFile = new File(sourceFileUri);

    if (!sourceFile.isFile()) {
         ...
    } else {
        try {      
            // open a URL connection to the Servlet
             FileInputStream fileInputStream = new FileInputStream(sourceFile);
             URL url = new URL(upLoadServerUri);

             conn = (HttpURLConnection) url.openConnection();
             conn.setDoInput(true);
             conn.setDoOutput(true);
             conn.setUseCaches(false);
             conn.setRequestMethod("POST");
             conn.setRequestProperty("Connection", "Keep-Alive");
             conn.setRequestProperty("ENCTYPE", "multipart/form-data");
             conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
             conn.setRequestProperty("uploaded_file", fileName);//This is just for info?

             dos = new DataOutputStream(conn.getOutputStream());
             dos.writeBytes(twoHyphens + boundary + lineEnd);
             dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\"; filename=\""+fileName+"\"" + lineEnd);//How put in here a resized bitmap?
             dos.writeBytes(lineEnd);

             //Here I'm lost!
             bytesAvailable = fileInputStream.available();
             bufferSize = Math.min(bytesAvailable, maxBufferSize);
             buffer = new byte[bufferSize];

             bytesRead = fileInputStream.read(buffer, 0, bufferSize); 

             //I think...
             //this is a way to transfer the file in little pieces to server, right?, wrong?
             //If anybody can explain this, step by step... THANKS!!!
             while (bytesRead > 0) {
                dos.write(buffer, 0, bufferSize);
                bytesAvailable = fileInputStream.available();
                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);
              }
             dos.writeBytes(lineEnd);
             dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
             serverResponseCode = conn.getResponseCode();
             String serverResponseMessage = conn.getResponseMessage();
             Log.i("uploadFile", "Respuesta HTTP es: " + serverResponseMessage + ": " + serverResponseCode);

             if(serverResponseCode == 200){
                 ...               
             }
             fileInputStream.close();
             dos.flush();
             dos.close();
        } catch (MalformedURLException ex) {
            ...
        } catch (Exception e) { 
            ... 
        }

        dialog.dismiss();      
        return serverResponseCode;

    } // End else block
}//End uploadFile()
Community
  • 1
  • 1
arickdev
  • 171
  • 2
  • 12

1 Answers1

3

Actually there are 2 ways to handle above case, mentioned below :

1] Make some arrangement at server side (in your webservice) so you can pass height & width while uploading image on server, this will reduce image size whatever height/width dimension you pass. This is first solution.

2] As per my understanding if you can reduce bitmap dimension by this code :

try
{
int inWidth = 0;
int inHeight = 0;

InputStream in = new FileInputStream(pathOfInputImage);

// decode image size (decode metadata only, not the whole image)
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, options);
in.close();
in = null;

// save width and height
inWidth = options.outWidth;
inHeight = options.outHeight;

// decode full image pre-resized
in = new FileInputStream(pathOfInputImage);
options = new BitmapFactory.Options();
// calc rought re-size (this is no exact resize)
options.inSampleSize = Math.max(inWidth/dstWidth, inHeight/dstHeight);
// decode full image
Bitmap roughBitmap = BitmapFactory.decodeStream(in, null, options);

// calc exact destination size
Matrix m = new Matrix();
RectF inRect = new RectF(0, 0, roughBitmap.getWidth(), roughBitmap.getHeight());
RectF outRect = new RectF(0, 0, dstWidth, dstHeight);
m.setRectToRect(inRect, outRect, Matrix.ScaleToFit.CENTER);
float[] values = new float[9];
m.getValues(values);

// resize bitmap
Bitmap resizedBitmap = Bitmap.createScaledBitmap(roughBitmap, (int) (roughBitmap.getWidth() * values[0]), (int) (roughBitmap.getHeight() * values[4]), true);

// save image
try
{
    FileOutputStream out = new FileOutputStream(pathOfOutputImage);
    resizedBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
}
catch (Exception e)
{
    Log.e("Image", e.getMessage(), e);
}
}
catch (IOException e)
{
   Log.e("Image", e.getMessage(), e);
}

After doing above coding steps, then you can use your image/bitmap uploading logic/code.

VVB
  • 7,363
  • 7
  • 49
  • 83
  • Actually the thing is if you want to completely rescale image then you can't go for interpreting – VVB Aug 20 '14 at 05:18
  • I think understand... 1: you get the width and height of the original image. 2: create a bitmap a little scaled (I don't know why), and I think that dstWidth and dstHeight are the pixel that I want, but I don't know how math.max works, this step is confusing to me. 3: Scale inRect to outRect. 4: Create a bitmap with a new size. 5: Compress bitmap. Something like that? – arickdev Aug 20 '14 at 05:52
  • It's a good and new way for me... I've seen many examples to resize images, but the problem is, I don't know how to use that bitmap without a Path from SD of device? :S – arickdev Aug 20 '14 at 06:00