I have been using recyclerview to display my contacts and show their basic data including user images. It works as it should, Picasso is great and I get a very cool looking list.
Right now I am trying to disable users to view images until validated - ie I want to disable viewing images to anyone who is not an authenticated user.
I have done this on my services and disabled anyone except my laravel app to open the image link. Now I face one issue - when I return image it is not a link, but it is in a byte[]
format,
and I cannot display it using Picasso. I could try and convert it to Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
and then convert bitmap to drawable like:
Drawable drawable = new BitmapDrawable(getResources(), bitmap);
, and then display drawable as image imageView.setImageDrawable(drawable);
but reading into this I found quite a few drawbacks.
My question would be what is the best way to display image using picasso or glide, and retrofit to return images for authenticated users only. Is there a different way I can return image from laravel service?
Is there a way to use the byte format with either picasso or glide? Or is there another format I can convert my byte[]
to display in the recyclerview, that would not negatively influence performance?
Currently displaying image with Picasso in my ContactsAdapter:
@Override
public void onBindViewHolder(ContactsAdapter.ContactsViewHolder holder, int position) {
Contact contact = contactList.get(position);
holder.userName.setText(contact.getUserName());
TextDrawable.IBuilder builder = TextDrawable.builder()
.beginConfig()
.withBorder(0)
.toUpperCase()
.endConfig()
.round();
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(contact.getUserId());
textDrawable = builder.build(contactList.get(position).getUserName().substring(0, 1), color);
holder.thumbNail.setImageDrawable(textDrawable);
Picasso.with(context)
.load(AppConfig.URL_PROFILE_PHOTO + contact.getThumbnailUrl()) // DISK URL WITH USER IMAGE NAME
.placeholder(textDrawable)
.error(textDrawable)
.transform(new CircleTransform())
.into(holder.thumbNail);
}
Laravel service converts link to image like this:
return Image::make($storagePath)->response();
I extracted the ProfileImage method and tried to modify it to use the service I got:
private void ProfileImage(HashMap<String, String> user, String name, String id) {
TokenManager tokenManager = TokenManager.getInstance(getSharedPreferences("prefs", MODE_PRIVATE));
ApiInterface apiService = ApiClient.createServiceWithAuth(ApiInterface.class, tokenManager);
ColorGenerator generator = ColorGenerator.MATERIAL;
int color = generator.getColor(id);
String firstLetter = name.substring(0, 1);
TextDrawable textDrawable = TextDrawable.builder().buildRect(firstLetter, color);
holder.thumbNail.setImageDrawable(textDrawable);
Call<ResponseBody> call = apiService.getUserImage(id);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
if (response.isSuccessful()) {
byte[] bytes = new byte[0];
try {
bytes = response.body().bytes();
Picasso.with(getApplicationContext())
.load(/** I CANNOT USE THE URL HERE */)
.placeholder(textDrawable)
.error(textDrawable)
.centerCrop()
.fit()
.into(holder.thumbNail);
} catch (IOException e) {
e.printStackTrace();
}
} else {
if (response.code() == 401) {
finish();
} else {
Log.d(TAG, "There was an error: " + response);
}
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(TAG, t.toString());
}
});
}
If you can switch to Glide
, you can use Glide.with().load(byte[] model)
directly
bytes = response.body().bytes();
Glide.with(getApplicationContext())
.load(bytes)
.placeholder(textDrawable)
.error(textDrawable)
.centerCrop()
.fitCenter()
.into(holder.thumbNail);