Splitusa
Splitusa

Reputation: 1181

Base64 encoding and viewing an image

What I am currently trying to do is the following:

Take a Picture, compress it to PNG, covert using Base64 and send it to a database through PHP. That all works like a charm. I can also decode the Base64 string and display the photo perfectly.

However, the problems seems to be that when I view the picture on my browser, it is not the same size as it should be (or at least I think).

This is the image that I took encoded and displayed in browser: enter image description here

Regardless of the phone, (Also tested on a Galaxy SII), the issue still remains. Do you guys have any idea what may be happening? Here are some ideas that I have but not sure... 1. Compressing the image too much - or when it compresses it changes something 2.Base64 encoding/decoding is messing up the photo and not displaying it correctly 3. When i place the image in an image view it modifies the size.

Again, It seems like that full image is not getting sent through, cause there is no way an image even a Galaxy sII image looks that small.

Here is the code that I am using: Android:

// CONVERT:
        ByteArrayOutputStream bao = new ByteArrayOutputStream();
        picture.compress(Bitmap.CompressFormat.PNG, 100, bao);
        Log.d(TAG, "AFTER. Height: " + picture.getHeight() + " Width: " + picture.getWidth());
        final byte[] ba = bao.toByteArray();

        //encode to string
        String photoTest = Base64.encodeToString(ba, Base64.DEFAULT);

//Camera on activity for result - save it as a bmp and place in imageview
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == CAMERA_PIC_REQUEST) {
            // do something
        }

        if (resultCode == Activity.RESULT_OK) {
            Log.d(TAG, "result ok");

            Bundle b = data.getExtras();
            picture = (Bitmap) b.get("data");
            imageView.setImageBitmap(picture);
        }
    }

IMAGE VIEW IN ANDROID:

<ImageView
        android:id="@+id/imageView1"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@drawable/icon"/>

PHP:

$image = base64_decode($_POST['image_data']);

Thank you for your help!

Upvotes: 2

Views: 2535

Answers (3)

Thiago Queiroz
Thiago Queiroz

Reputation: 131

I had the same problem, this is how i solved my problem, this method will open the default camera app, save the image to a temporary folder and convert it do Base64/ByteArray.

1 - Click Listener to open the camera app

// My ImageButton click Listener
ibt_foto.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {

        String tempDir = Environment.getExternalStorageDirectory() + "/folder/";
        String path = Environment.getExternalStorageDirectory() + "/folder/photo1.jpg";
        prepareDirectory();
        File file = new File(path);
        Uri outputFileUri = Uri.fromFile(file);
        Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
        startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
    }
});

2 - Creating folder

private boolean prepareDirectory() {
    try {
        if (makedirs()) {
            return true;
        } else {
            return false;
        }
    } catch (Exception e) {
        e.printStackTrace();
        Toast.makeText(this, "Could not initiate File System.. Is Sdcard mounted properly?", Toast.LENGTH_LONG).show();
        return false;
    }
}

private boolean makedirs() {

    File tempdir = new File(tempDir);
    if (!tempdir.exists()) {
        tempdir.mkdirs();
    }

    /*
    // Use this if you want to delete older files
    if (tempdir.isDirectory()) {
        File[] files = tempdir.listFiles();
        for (File file : files) {
            if (!file.delete()) {
                System.out.println("Failed to delete " + file);
            }
        }
    }
    */

    return (tempdir.isDirectory());
}

3 - Handling result from camera app

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    System.gc(); 

    if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
        if (resultCode == RESULT_OK) {
            try {

                // Get image
                BitmapFactory.Options options = new BitmapFactory.Options();
                options.inSampleSize = 3;
                Bitmap imageBitmap = BitmapFactory.decodeFile(path, options);

                // Converting to ByteArray and Base64
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                boolean validaCompressao = imageBitmap.compress(Bitmap.CompressFormat.JPEG, 75, outputStream);
                byte[] fotoBinario = outputStream.toByteArray();

                String encodedImage = Base64.encodeToString(fotoBinario, Base64.DEFAULT);

                // setting image to my ImageButton
                ibt_foto.setImageBitmap(imageBitmap);

            } catch (Exception e) {
                Toast.makeText(this, "Picture Not taken",Toast.LENGTH_LONG).show();e.printStackTrace();
            }
        } else if (resultCode == RESULT_CANCELED) {
            Toast.makeText(this, "Picture was not taken 1 ", Toast.LENGTH_SHORT);
        } else {
            Toast.makeText(this, "Picture was not taken 2 ", Toast.LENGTH_SHORT);
        }
    }
}

Upvotes: 0

Splitusa
Splitusa

Reputation: 1181

How I solved it: Turns out that when you save the photo like I did above, it only returns the thumbnail version of the photo and not the full sized photo. I had to add EXTRA_OUTPUT to my intent, save it to the sd-card, then compress. If someone has similar issues, please message me.

Upvotes: 1

Campadrenalin
Campadrenalin

Reputation: 243

Base64 leaves binary data exactly intact, it doesn't do resizing gimmicks. I'm guessing the problem line is picture.compress(Bitmap.CompressFormat.PNG, 100, bao);, but this isn't really my field.

Upvotes: 1

Related Questions