
com.bumptech.glide.load.model.DataUrlLoader Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of glide Show documentation
Show all versions of glide Show documentation
A fast and efficient image loading library for Android focused on smooth scrolling.
package com.bumptech.glide.load.model;
import android.util.Base64;
import androidx.annotation.NonNull;
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.Options;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.signature.ObjectKey;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* A simple model loader for loading data from a Data URL String.
*
* Data URIs use the "data" scheme.
*
*
See http://www.ietf.org/rfc/rfc2397.txt for a complete description of the 'data' URL scheme.
*
*
Briefly, a 'data' URL has the form:
*
*
data:[mediatype][;base64],some_data
*
* @param The type of Model that we can retrieve data for, e.g. {@link String}.
* @param The type of data that can be opened, e.g. {@link InputStream}.
*/
public final class DataUrlLoader implements ModelLoader {
private static final String DATA_SCHEME_IMAGE = "data:image";
private static final String BASE64_TAG = ";base64";
private final DataDecoder dataDecoder;
// Public API.
@SuppressWarnings("WeakerAccess")
public DataUrlLoader(DataDecoder dataDecoder) {
this.dataDecoder = dataDecoder;
}
@Override
public LoadData buildLoadData(
@NonNull Model model, int width, int height, @NonNull Options options) {
return new LoadData<>(
new ObjectKey(model), new DataUriFetcher<>(model.toString(), dataDecoder));
}
@Override
public boolean handles(@NonNull Model model) {
// We expect Model to be a Uri or a String, both of which implement toString() efficiently. We
// should reconsider this implementation before adding any new Model types.
return model.toString().startsWith(DATA_SCHEME_IMAGE);
}
/**
* Allows decoding a specific type of data from a Data URL String.
*
* @param The type of data that can be opened.
*/
public interface DataDecoder {
Data decode(String uri) throws IllegalArgumentException;
void close(Data data) throws IOException;
Class getDataClass();
}
private static final class DataUriFetcher implements DataFetcher {
private final String dataUri;
private final DataDecoder reader;
private Data data;
DataUriFetcher(String dataUri, DataDecoder reader) {
this.dataUri = dataUri;
this.reader = reader;
}
@Override
public void loadData(@NonNull Priority priority, @NonNull DataCallback super Data> callback) {
try {
data = reader.decode(dataUri);
callback.onDataReady(data);
} catch (IllegalArgumentException e) {
callback.onLoadFailed(e);
}
}
@Override
public void cleanup() {
try {
reader.close(data);
} catch (IOException e) {
// Ignored.
}
}
@Override
public void cancel() {
// Do nothing.
}
@NonNull
@Override
public Class getDataClass() {
return reader.getDataClass();
}
@NonNull
@Override
public DataSource getDataSource() {
return DataSource.LOCAL;
}
}
/**
* Factory for loading {@link InputStream}s from data uris.
*
* @param The type of Model we can obtain data for, e.g. String.
*/
public static final class StreamFactory implements ModelLoaderFactory {
private final DataDecoder opener;
public StreamFactory() {
opener =
new DataDecoder() {
@Override
public InputStream decode(String url) {
if (!url.startsWith(DATA_SCHEME_IMAGE)) {
throw new IllegalArgumentException("Not a valid image data URL.");
}
int commaIndex = url.indexOf(',');
if (commaIndex == -1) {
throw new IllegalArgumentException("Missing comma in data URL.");
}
String beforeComma = url.substring(0, commaIndex);
if (!beforeComma.endsWith(BASE64_TAG)) {
throw new IllegalArgumentException("Not a base64 image data URL.");
}
String afterComma = url.substring(commaIndex + 1);
byte[] bytes = Base64.decode(afterComma, Base64.DEFAULT);
return new ByteArrayInputStream(bytes);
}
@Override
public void close(InputStream inputStream) throws IOException {
inputStream.close();
}
@Override
public Class getDataClass() {
return InputStream.class;
}
};
}
@NonNull
@Override
public ModelLoader build(@NonNull MultiModelLoaderFactory multiFactory) {
return new DataUrlLoader<>(opener);
}
@Override
public void teardown() {
// Do nothing.
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy