-
Notifications
You must be signed in to change notification settings - Fork 6.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Data URI scheme (e.g. Base64) #556
Comments
Can you please elaborate more on what are you trying to achieve, for example:
|
Sorry if i wasn't clear enough, (english is not my first language)
it's stored in a remote server (firebase), so it coud be a json object or a string stream.
Yes to both cases, its a unique stable id.
No. it's allways the same format. What I'm currently doing is this:
|
You mentioned Firebase so I went ahead and checked out what it is, I've never used it, but hopefully I got it mostly right: Glide
.with(context)
.load(new FirebaseImage("the-stable-id-you-mentioned"))
.placeholder(android.R.color.darker_gray)
.error(android.R.color.black)
.into(imageView)
; public class FirebaseImage {
// final Firebase fb; // see FirebaseImageModelLoader ctor
private final String key;
public FirebaseImage(String key) {
this.key = key;
}
public String getDataUri(Firebase fb) throws InterruptedException, FirebaseException {
return (String)syncGetValue(fb.child("images").child(key));
}
private static Object syncGetValue(Firebase image) throws InterruptedException, FirebaseException {
// hacky, but couldn't find better API :(
final AtomicReference<Object> resultRef = new AtomicReference<>();
final AtomicReference<FirebaseException> thrownRef = new AtomicReference<>();
final CountDownLatch latch = new CountDownLatch(1);
image.addListenerForSingleValueEvent(new ValueEventListener() {
@Override public void onDataChange(DataSnapshot snapshot) {
resultRef.set(snapshot.getValue());
latch.countDown();
}
@Override public void onCancelled(FirebaseError error) {
thrownRef.set(error.toException());
latch.countDown();
}
});
latch.await();
FirebaseException thrown = thrownRef.get();
Object result = resultRef.get();
if (thrown != null) {
throw thrown;
} else if (result == null) {
throw new NullPointerException("No data returned from " + image);
} else {
return result;
}
}
}
// TODO https://github.com/bumptech/glide/wiki/Configuration#creating-a-glidemodule
public class FirebaseGlideModule implements GlideModule {
@Override public void applyOptions(Context context, GlideBuilder builder) {
}
@Override public void registerComponents(Context context, Glide glide) {
Firebase fb = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
fb.authWithPassword("", "", null); // TODO fire auth to background if needed, see FirebaseImageModelLoader ctor
glide.register(FirebaseImage.class, InputStream.class, new FirebaseImageModelLoader.Factory(fb));
}
}
// TODO read https://github.com/bumptech/glide/wiki/Downloading-custom-sizes-with-Glide
class FirebaseImageModelLoader implements StreamModelLoader<FirebaseImage> {
private final Firebase fb;
public FirebaseImageModelLoader(Firebase fb) {
this.fb = fb; // TODO *alternatively* add a Firebase field to FirebaseImage and use that from model in DataFetcher
}
@Override public DataFetcher<InputStream> getResourceFetcher(final FirebaseImage model, int width, int height) {
return new DataFetcher<InputStream>() {
private Thread decodingThread;
@Override public InputStream loadData(Priority priority) throws Exception {
decodingThread = Thread.currentThread();
// somehow make sure that fb is ready after authWithPassword is called
String dataUri = model.getDataUri(fb);
String base64 = dataUri.substring("data:image/jpeg;base64,".length());
// depending on how you encoded it, the below is just a guess:
// here the full base64 is decoded into bytes and the bytes will be parsed by Glide
return new ByteArrayInputStream(Base64.decode(base64, Base64.NO_WRAP | Base64.URL_SAFE));
// if you don't want to delay decoding you can use something like:
// Base64InputStream (http://stackoverflow.com/a/19981216/253468)
// here the base64 bytes are passed to Base64InputStream and that to Glide
// so base64 decoding will be done later when Glide reads from the stream.
return new Base64InputStream(new ByteArrayInputStream(base64.getBytes("utf-8")), Base64.NO_WRAP | Base64.URL_SAFE);
}
@Override public String getId() {
return model.key; // for cache
}
@Override public void cancel() {
// don't do this if it's likely to display in the future (read doc of cancel)
decodingThread.interrupt(); // should fly out from await()
// note that this may be not the correct way to cancel, just an example
// Glide may not like interrupted threads in its pool
// this may cause problems in future loads which is not good, test it
}
@Override public void cleanup() {
decodingThread = null;
}
};
}
public static class Factory implements ModelLoaderFactory<FirebaseImage, InputStream> {
private final Firebase fb;
public Factory(Firebase fb) {
this.fb = fb;
}
@Override public ModelLoader<FirebaseImage, InputStream> build(Context context, GenericLoaderFactory factories) {
return new FirebaseImageModelLoader(fb);
}
@Override public void teardown() {
// only called if Glide.register is called with same first 2 args again
fb.onDisconnect().cancel(); // TODO or whatever you call to disconnect
}
}
} Please note that I only tested the Glide part, I don't have Firebase. So you have to make sure that |
Thank you very much!!! that's amazingly helpfull!! Roberto |
Thanks @TWiStErRob! |
@sjudd couldn't we incorporate this somehow into StringLoader so it's handled by default? At least for simple data Uris. |
Do you mean firebase? or a base 64 image string? |
Just data URIs. As used in CSS or |
Ah I see what you mean, sure we could look in to that, it probably wouldn't be super hard. |
Hi I had and image encode as string base 64, can I load this image with glide ? |
@ReyesMagos You can do the same as above just have replace |
@pullmann did it work in the end? Please share with future readers of this issue. |
@TWiStErRob , I saw the issue closed so I didn't comment on it, the FirebaseImage model worked like a charm, almost copyed and pasted your code, just replaced the firebase urls. |
Glad to hear, thanks. My views: Don't worry about closed issues, the worst that can happen is that you get no response (I've experienced this in other trackers and try to no do it here). For example I use close to signify "our work is done here, we think there's enough info provided". This is to keep the issue tracker cleaner, don't let solved issues linger as open; lot of times people only write back when there's another follow-up issue, not when it's working. Obviously we can reopen or continue discussion as needed. I'm pretty sure even a "closed as wontfix" can turn around with a simple sentence that brings in new information and destroys all the arguments before it. Communications FTW! |
Hello. I am looking to use glide to load a base64 encoded image that is packed in json which is downloaded from a given url. As mentioned above to @ReyesMagos, this is possible using the example above without the Firebase references, but I am having trouble separating out the Firebase references and keeping what is actually necessary for this to happen. I would like to use glide to handle the network request as well, but I cannot figure out where I would put it in the above example. Thanks for any help you might be able to provide. EDIT: I forgot to mention that the specified url requires a json struct containing an image 'key'. |
@sugarmanz see above commit for some examples, each package is a different approach. In your use case you have to make the request based on the image key, but Glide can cache the key->image if you want. |
@TWiStErRob That's exactly what I needed. Great library by the way. |
@TWiStErRob Hello, my server returned data is base64 format How do I use the glide, need and hope to answer thanks |
@TWiStErRob I saw the above comments but unable to solve my issue. Here, what I am trying to achieve. I have image on server and while making D/skia: --- SkImageDecoder::Factory returned null
D/skia: --- SkImageDecoder::Factory returned null Here is the apparch I am doing public class ImageLoaderUtils {
private Context context;
private BaseURL baseURL;
public ImageLoaderUtils(Context Context context) {
this.context = context;
baseURL = new BaseURL();
}
private String buildUserImageUrl(long clientId) {
return baseURL.getUrl() + ApiEndPoints.CLIENTS + "/" + clientId + "/images";
}
private GlideUrl buildGlideUrl(String imageUrl) {
return new GlideUrl(imageUrl, new LazyHeaders.Builder()
.addHeader(SelfServiceInterceptor.HEADER_TENANT, "default")
.addHeader(SelfServiceInterceptor.HEADER_AUTH, "token...")
.addHeader(SelfServiceInterceptor.HEADER_ACCEPT, "text/plain")
.build());
}
public void loadUserProfileImage(final CircularImageView imageView) {
Glide.with(context)
.load(buildGlideUrl(buildUserImageUrl(id)))
.asBitmap()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.placeholder(R.drawable.ic_person_black_24dp)
.error(R.drawable.ic_person_black_24dp)
.centerCrop()
.into(imageView);
}
} I know the response type with prefix I am using glide version 3.7.0 |
For people using Glide 4.x, referring to this document in their official docs might be useful. |
So, I actually just read this in the documentation (linked above):
I wonder why it's not working in my case, then... I get this crash:
|
So... just reporting here that I did figure out the issue: if I feed Glide with a |
Previously we only supported data uris if they were provided as Strings. Fixes bumptech#556.
------------- Include the debug aar in release artifacts for Android projects. We removed the release variant a while ago to speed up the build, which has the side affect of removing the release aar from artifacts. Since we expect the debug and release variants to be identical (hence why we disabled the release variant), it should be safe to just use the debug aar instead. We will have to specify it explicitly since android’s rules unsurprisingly only add the release variant by default. ------------- Bump version to 4.6.0 ------------- Update readme to 4.6.0 Also removes the old v4 dependency from maven deps, I don’t think it’s necessary. ------------- Change update_javadocs to use debugJavadocJar instead of release. We’ve disabled the release variant. ------------- Bump version to 4.7.0-SNAPSHOT ------------- Add POM dependencies explicitly. Fixes bumptech#2863. ------------- Bump version to 4.6.1 ------------- Update readme to 4.6.1 ------------- Fix param mistake (bumptech#2873) ------------- Update SimpleTarget javadoc to match v4 API. ------------- Add javadoc for RequestOptions.apply/RequestBuilder.apply. Related to bumptech#2858. ------------- Add support for Uri data uris. Previously we only supported data uris if they were provided as Strings. Fixes bumptech#556. ------------- Make GlideBuilder.build package private. It shouldn’t have been made visible and can’t safely be used directly outside of the library. Fixes bumptech#2885 ------------- Handle notifications in MultiFetcher after cancellation. We can’t guarantee that every fetcher implementation will strictly avoid notifying after they’ve been cancelled. This also improves the behavior in VolleyStreamFetcher so that it attempts to avoid notifying after cancel, although it still doesn’t make any strict guarantee. Fixes bumptech#2879 ------------- Re-enable -Werror for java compilation. Related to bumptech#2886. ------------- Fix a deprecation warning in DataUriTest. ------------- gradle 4.5.1 ------------- deprecate fragments ------------- add @deprecated to javadoc and suppress deprecations in code ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=99229725401d5777e059da7b6331134bf73fbcdf ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=185535564
I need some help on implementing a data uri scheme image decoder, I get string containing images encoded in base64
with something like this: :
"data:image/jpeg;base64,/9j/4AAQSkZJ.....TY3OD=="
Is there an existing decoder or an example on how to implement it in glise?
I'm currently using a modified version of the "Displaying Bitmaps Efficiently" example, but the caching is really basic.
Thanks in Advance.
Roberto.
The text was updated successfully, but these errors were encountered: