I'm developing an app that deals with pictures and using parse.com
services as a backend. At some point I had to choose between:
100x100
for thumbnails, 400x400
for bigger views, 1000x1000
for fullscreen views;1000x1000
version, and scale it down when needed, possibly server-side.The solution I'm currently working on is a mixture of the two: I hold 100x100
for thumbnails, 1000x1000
for fullscreen views and would like to scale it down for any other need. I started working on a Cloud Code function to achieve this. My wish is to pass to the function the width of the current view, so to make the image adaptable to the client's need.
var Image = require("parse-image");
Parse.Cloud.define("getPicture", function(request, response) {
var url = request.params.pictureUrl;
var objWidth = request.params.width / 2;
Parse.Cloud.httpRequest({
url: url
}).then(function(resp) {
var i = new Image();
return i.setData(resp.buffer);
}).then(function(i) {
var scale = objWidth / i.width();
if (scale >= 1) {
response.success(i.data());
}
return i.scale({
ratio: scale
});
}).then(function(i) {
return i.data();
}).then(function(data) {
response.success(data);
});
});
I have two questions:
is this approach correct, or should I better simply store a middle-sized version of the image (like 400x400
)? Would this determine too many calls to the cloud code function? (I'm not aware of any parse.com
restriction for the number of cloud functions calls, but there might be)
What kind of object is i.data()
returning, and how can I get a Bitmap
from it? From the Android app I'm calling:
HashMap<String, Object> params = new HashMap<>();
params.put("pictureUrl",getUrl());
params.put("width", getWidth());
ParseCloud.callFunctionInBackground("getPicture", params, new FunctionCallback<Object>() {
@Override
public void done(Object object, ParseException e) {
//here I should use BitmapFactory.decodeByteArray(...)
//but object is definitely not a byte[] !
//From debugging it looks like a List<Integer>,
//but I don't know how to get a Bitmap from it.
}
});
Approach looks good.
Since the return value of Parse API is JSON, only way you can send binary data (an image) back is either as JSON Integer array or by using either Hex or Base64 encoded value of the binary data.
You can return base64
string by using Buffer#toString() method of Parse Cloud as shown below. base64
strings are smaller in size when compared to hex
encoding, hence, are preferred.
response.success(data.toString('base64'));
On the Android side, code given below can be used which decodes the base 64 string into byte[]
so that can be used in Bitmapfactory#decodeByteArray
.
ParseCloud.callFunctionInBackground("getPicture", params,
new FunctionCallback<String>() {
@Override
public void done(String object,
ParseException e) {
byte[] imgBytes = Base64.decode(object, Base64.DEFAULT);
if (imgBytes.length > 0) {
Bitmap bitmap = BitmapFactory.decodeByteArray(imgBytes, 0, imgBytes.length);
((ImageView) findViewById(R.id.image_view)).setImageBitmap(bitmap);
}
}
}
);
I have tested the changes proposed above, they work just fine.
Note: Please note that R.id.image_view
is for reference purpose, you will have to use id
of ImageView
as applicable to your project
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With