Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send Base64 image from Android with JSON to php webservice, decode, save to SQL

Like the description says, I am taking a photo in Android. It is compressed and added to a byte[] then base64encoded. It sends with JSON to my webservice where it is "supposed" to be decoded and saved in a SQL table row. I can save the encoded string in a separate row so I know it's getting there.

Can anyone look at this and show me where I am doing it wrong? *Sorry for the lengthy code. I don't want to miss something if being offered help!

ANDROID SIDE

@Override
    protected String doInBackground(String... args) {
        // TODO Auto-generated method stub
        // Check for success tag

        int success;
        stream = new ByteArrayOutputStream();
        picture.compress(Bitmap.CompressFormat.JPEG, 50, stream);
        image = stream.toByteArray();

        String ba1 = Base64.encodeToString(image, Base64.DEFAULT);

        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(MainScreen.this);
        String post_username = sp.getString("username", "anon");

        try {
            ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
            params.add(new BasicNameValuePair("username", post_username));
            params.add(new BasicNameValuePair("picture", ba1));

           JSONObject json = jsonParser.makeHttpRequest(POST_COMMENT_URL,
                    "POST", params);


            success = json.getInt(TAG_SUCCESS);
            if (success == 1) {
                Log.d("Picture Added!", json.toString());
                //finish();
                return json.getString(TAG_MESSAGE);
            } else {
                Log.d("Upload Failure!", json.getString(TAG_MESSAGE));
                return json.getString(TAG_MESSAGE);

            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return null;

    }

    protected void onPostExecute(String file_url) {
        // dismiss the dialog once product deleted
        pDialog.dismiss();
        if (file_url != null) {
            Toast.makeText(MainScreen.this, file_url, Toast.LENGTH_LONG)
                    .show();
        }

    }
}

}

PHP SIDE

<?php
require("config.inc.php");
if (!empty($_POST)) {
    $user = $_POST['username'];
    $data = $_POST['picture'];
    $data = base64_decode($data);
    $im = imagecreatefromstring($data);
    header('Content-Type: image/jpeg', true);
    ob_start();
    imagejpeg($im);
    $imagevariable = ob_get_contents();
    ob_end_clean();

$query = "INSERT INTO pictures ( username, photo, rawdata ) VALUES ( :user, :photo, :raw ) ";

$query_params = array(
    ':user' => $user,
    ':photo' => $imagevariable,
    ':raw' => $_POST['picture']
);

try {
    $stmt   = $db->prepare($query);
    $result = $stmt->execute($query_params);
}
catch (PDOException $ex) {
    $response["success"] = 0;
    $response["message"] = "Database Error. Couldn't add post!";
    die(json_encode($response));
}
$response["success"] = 1;
$response["message"] = "Picture Successfully Added!";
echo json_encode($response);

} else {
}
?>
like image 528
JeffK Avatar asked Aug 28 '13 18:08

JeffK


1 Answers

I wanted to post my solution in case anyone else is having trouble with this. I always come to S.O. for answers so now it's my turn to help someone out. I was having problems with out of memory errors using the bitmaps. I changed it to a multipart post to upload the picture as a file and a string like their name but you could add any string to it. The first part is the android side and below that is the php for the database. The picture is added to a file in the directory with the move file method. The database stores the path to that picture. I searched for two days to piece it together all from stack overflow posts.

ANDROID

public void onClick(View v) {
    if (v.getId() == R.id.capture_btn) {
        try {

            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(intent, CAMERA_IMAGE_CAPTURE);

        } catch (ActivityNotFoundException anfe) {

            String errorMessage = "Whoops - your device doesn't support capturing images!";
            Toast toast = Toast.makeText(this, errorMessage,
                    Toast.LENGTH_SHORT);
            toast.show();

        }

    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == CAMERA_IMAGE_CAPTURE
            && resultCode == Activity.RESULT_OK) {
        getLastImageId();

        new PostPicture().execute();
    }
}

private int getLastImageId() {
    // TODO Auto-generated method stub
    final String[] imageColumns = { MediaStore.Images.Media._ID,
            MediaStore.Images.Media.DATA };
    final String imageOrderBy = MediaStore.Images.Media._ID + " DESC";
    Cursor imageCursor = managedQuery(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageColumns,
            null, null, imageOrderBy);
    if (imageCursor.moveToFirst()) {
        int id = imageCursor.getInt(imageCursor
                .getColumnIndexOrThrow(MediaStore.Images.Media._ID));
        fullPath = imageCursor.getString(imageCursor
                .getColumnIndex(MediaStore.Images.Media.DATA));
        Log.d("pff", "getLastImageId: :id " + id);
        Log.d("pff", "getLastImageId: :path " + fullPath);
        return id;

    } else {
        return 0;
    }
}

class PostPicture extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(MainScreen.this);
        pDialog.setMessage("Uploading Picture");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();

    }

    @Override
    protected String doInBackground(String... args) {
        // TODO Auto-generated method stub
        // Check for success tag

        HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost("http://www.your-php-page.php");

        try {

            MultipartEntity entity = new MultipartEntity(
                    HttpMultipartMode.BROWSER_COMPATIBLE);
            File file = new File(fullPath);
            cbFile = new FileBody(file, "image/jpeg");
            Log.d("sending picture", "guest name is " + guest_name);
            Log.d("Sending picture", "guest code is " + guest_code);
            entity.addPart("name",
                    new StringBody(guest_name, Charset.forName("UTF-8")));
            entity.addPart("code",
                    new StringBody(guest_code, Charset.forName("UTF-8")));
            entity.addPart("picture", cbFile);
            post.setEntity(entity);

            HttpResponse response1 = client.execute(post);
            HttpEntity resEntity = response1.getEntity();
            String Response = EntityUtils.toString(resEntity);
            Log.d("Response", Response);

        } catch (IOException e) {
            Log.e("asdf", e.getMessage(), e);

        }
        return null;

    }

    protected void onPostExecute(String file_url) {
        // dismiss the dialog once product deleted
        pDialog.dismiss();
        if (file_url != null) {
            Toast.makeText(MainScreen.this, file_url, Toast.LENGTH_LONG)
                    .show();
        }

    }
}

And this is the PHP. Also note that I am including my Database log in page. You can enter your d.b. password and log in here but I choose not to.

<?php
require("config.inc.php");
if (!empty($_POST)) {

if (empty($_POST['name'])) {
    $response["success"] = 0;
    $response["message"] = "Did not receive a name";
    die(json_encode($response));        
} else {
    $name = $_POST['name'];
}


if (empty($_FILES['picture'])) {
    $response["success"] = 0;
    $response["message"] = "Did not receive a picture";
    die(json_encode($response));        
} else {
    $file = $_FILES['picture'];
}


    $target_path = "uploads/whatever-you-want-it-to-be/";
            // It could be any string value above

    /* Add the original filename to our target path.  
    Result is "uploads/filename.extension" */
    $target_path = $target_path . basename( $_FILES['picture']['name']); 

    if(move_uploaded_file($_FILES['picture']['tmp_name'], $target_path)) {
        echo "The file ".  basename( $_FILES['picture']['name']). 
        " has been uploaded";
    } else{
        $response["success"] = 0;
        $response["message"] = "Database Error. Couldn't upload file.";
        die(json_encode($response));
    }

} else {
    $response["success"] = 0;
    $response["message"] = "You have entered an incorrect code. Please try again.";
    die(json_encode($response));
}

$query = "INSERT INTO name-of-table ( directory, name, photo ) VALUES ( directory, :name, :photo ) ";

$query_params = array(
    ':directory' => $directory,
    ':name' => $name,
    ':photo' => $_FILES['picture']['name']
        );

try {
    $stmt   = $db->prepare($query);
    $result = $stmt->execute($query_params);
}
catch (PDOException $ex) {
    $response["success"] = 0;
    $response["message"] = "Database Error. Couldn't add path to picture";
    die(json_encode($response));
}
$response["success"] = 1;
$response["message"] = "Picture Successfully Added!";
die (json_encode($response));


}

?>
like image 71
JeffK Avatar answered Sep 26 '22 05:09

JeffK