下面列出了怎么用com.bumptech.glide.load.Transformation的API类实例代码及写法,或者点击链接到github查看源代码。
public GifState(GifHeader header, byte[] data, Context context,
Transformation<Bitmap> frameTransformation, int targetWidth, int targetHeight,
GifDecoder.BitmapProvider provider, BitmapPool bitmapPool, Bitmap firstFrame) {
if (firstFrame == null) {
throw new NullPointerException("The first frame of the GIF must not be null");
}
gifHeader = header;
this.data = data;
this.bitmapPool = bitmapPool;
this.firstFrame = firstFrame;
this.context = context.getApplicationContext();
this.frameTransformation = frameTransformation;
this.targetWidth = targetWidth;
this.targetHeight = targetHeight;
bitmapProvider = provider;
}
private GifDrawableResource decode(byte[] data, int width, int height, GifHeaderParser parser, GifDecoder decoder) {
final GifHeader header = parser.parseHeader();
if (header.getNumFrames() <= 0 || header.getStatus() != GifDecoder.STATUS_OK) {
// If we couldn't decode the GIF, we will end up with a frame count of 0.
return null;
}
Bitmap firstFrame = decodeFirstFrame(decoder, header, data);
if (firstFrame == null) {
return null;
}
Transformation<Bitmap> unitTransformation = UnitTransformation.get();
GifDrawable gifDrawable = new GifDrawable(context, provider, bitmapPool, unitTransformation, width, height,
header, data, firstFrame);
return new GifDrawableResource(gifDrawable);
}
DecodeJob(EngineKey resultKey, int width, int height, DataFetcher<A> fetcher,
DataLoadProvider<A, T> loadProvider, Transformation<T> transformation, ResourceTranscoder<T, Z> transcoder,
DiskCacheProvider diskCacheProvider, DiskCacheStrategy diskCacheStrategy, Priority priority, FileOpener
fileOpener) {
this.resultKey = resultKey;
this.width = width;
this.height = height;
this.fetcher = fetcher;
this.loadProvider = loadProvider;
this.transformation = transformation;
this.transcoder = transcoder;
this.diskCacheProvider = diskCacheProvider;
this.diskCacheStrategy = diskCacheStrategy;
this.priority = priority;
this.fileOpener = fileOpener;
}
private void onCaptureClicked() {
orderEnforcer.reset();
Stopwatch fastCaptureTimer = new Stopwatch("Capture");
camera.capture((jpegData, frontFacing) -> {
fastCaptureTimer.split("captured");
Transformation<Bitmap> transformation = frontFacing ? new MultiTransformation<>(new CenterCrop(), new FlipTransformation())
: new CenterCrop();
GlideApp.with(this)
.asBitmap()
.load(jpegData)
.transform(transformation)
.override(cameraPreview.getWidth(), cameraPreview.getHeight())
.into(new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
fastCaptureTimer.split("transform");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
resource.compress(Bitmap.CompressFormat.JPEG, 80, stream);
fastCaptureTimer.split("compressed");
byte[] data = stream.toByteArray();
fastCaptureTimer.split("bytes");
fastCaptureTimer.stop(TAG);
controller.onImageCaptured(data, resource.getWidth(), resource.getHeight());
}
@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
controller.onCameraError();
}
});
});
}
/**
* Transform resources with the given {@link Transformation}s. Replaces any existing transformation or
* transformations.
*
* @param transformations the transformations to apply in order.
* @return This request builder.
*/
public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> transform(
Transformation<ResourceType>... transformations) {
isTransformationSet = true;
if (transformations.length == 1) {
transformation = transformations[0];
} else {
transformation = new MultiTransformation<ResourceType>(transformations);
}
return this;
}
@SuppressWarnings("unchecked")
public void setFrameTransformation(Transformation<Bitmap> transformation) {
if (transformation == null) {
throw new NullPointerException("Transformation must not be null");
}
requestBuilder = requestBuilder.transform(transformation);
}
private Resource<Bitmap> getTransformedFrame(Bitmap currentFrame, Transformation<Bitmap> transformation,
GifDrawable drawable) {
// TODO: what if current frame is null?
Resource<Bitmap> bitmapResource = factory.buildFrameResource(currentFrame, bitmapPool);
Resource<Bitmap> transformedResource = transformation.transform(bitmapResource,
drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
if (!bitmapResource.equals(transformedResource)) {
bitmapResource.recycle();
}
return transformedResource;
}
public void setFrameTransformation(Transformation<Bitmap> frameTransformation, Bitmap firstFrame) {
if (firstFrame == null) {
throw new NullPointerException("The first frame of the GIF must not be null");
}
if (frameTransformation == null) {
throw new NullPointerException("The frame transformation must not be null");
}
state.frameTransformation = frameTransformation;
state.firstFrame = firstFrame;
frameLoader.setFrameTransformation(frameTransformation);
}
public EngineKey(String id, Key signature, int width, int height, ResourceDecoder cacheDecoder,
ResourceDecoder decoder, Transformation transformation, ResourceEncoder encoder,
ResourceTranscoder transcoder, Encoder sourceEncoder) {
this.id = id;
this.signature = signature;
this.width = width;
this.height = height;
this.cacheDecoder = cacheDecoder;
this.decoder = decoder;
this.transformation = transformation;
this.encoder = encoder;
this.transcoder = transcoder;
this.sourceEncoder = sourceEncoder;
}
@SuppressWarnings("rawtypes")
public EngineKey buildKey(String id, Key signature, int width, int height, ResourceDecoder cacheDecoder,
ResourceDecoder sourceDecoder, Transformation transformation, ResourceEncoder encoder,
ResourceTranscoder transcoder, Encoder sourceEncoder) {
return new EngineKey(id, signature, width, height, cacheDecoder, sourceDecoder, transformation, encoder,
transcoder, sourceEncoder);
}
private GifDrawableTransformation[] toGifTransformations(Transformation<Bitmap>[] bitmapTransformations) {
GifDrawableTransformation[] transformations = new GifDrawableTransformation[bitmapTransformations.length];
for (int i = 0; i < bitmapTransformations.length; i++) {
transformations[i] = new GifDrawableTransformation(bitmapTransformations[i], glide.getBitmapPool());
}
return transformations;
}
/**
* 获取图片处理效果加载配置
* @param options {@link RequestOptions}
* @param transformation {@link Transformation} 图形效果
* @return {@link RequestOptions}
*/
public static RequestOptions transformationOptions(final RequestOptions options, final Transformation transformation) {
if (options != null) {
try {
options.transform(transformation);
} catch (Exception e) {
LogPrintUtils.eTag(TAG, e, "transformationOptions");
}
}
return options;
}
private void loadImageView(Object object, int placeholderId, int errorId, Transformation transform, ImageView imageView){
DrawableRequestBuilder builder = load(object, with());
if(builder != null){
// 设置占位图
if(placeholderId != -1) builder.placeholder(placeholderId);
// 设置加载错误时占位图
if(errorId != -1) builder.error(errorId);
// 设置 transform
if(transform != null) builder.bitmapTransform(transform);
// 加载到图片
builder.into(imageView);
}
}
private BitmapDrawable transformDrawable(Drawable drawable, Transformation<Bitmap> transform, int size) {
// render original
Bitmap bitmap = Bitmap.createBitmap(size, size, Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, size, size);
drawable.draw(canvas);
// make rounded
Resource<Bitmap> original = BitmapResource.obtain(bitmap, Glide.get(getContext()).getBitmapPool());
Resource<Bitmap> rounded = transform.transform(original, size, size);
if (!original.equals(rounded)) {
original.recycle();
}
return new BitmapDrawable(getResources(), rounded.get());
}
private static void displayAlbum(ImageView imageView, String path, Transformation<Bitmap> transformation,
int placeHoder) {
Context context = imageView.getContext();
RequestOptions options = new RequestOptions().error(placeHoder).placeholder(placeHoder).diskCacheStrategy(
DiskCacheStrategy.RESOURCE);
if (transformation != null) {
options = options.transforms(new CenterCrop(), transformation);
} else {
options = options.transform(new CenterCrop());
}
Glide.with(context).asDrawable().apply(options).load(Uri.fromFile(new File(path))).into(imageView);
}
public static <A, T, Z, R> GenericRequest<A, T, Z, R> obtain(
LoadProvider<A, T, Z, R> loadProvider,
A model,
Key signature,
Context context,
Priority priority,
Target<R> target,
float sizeMultiplier,
Drawable placeholderDrawable,
int placeholderResourceId,
Drawable errorDrawable,
int errorResourceId,
Drawable fallbackDrawable,
int fallbackResourceId,
RequestListener<? super A, R> requestListener,
RequestCoordinator requestCoordinator,
Engine engine,
Transformation<Z> transformation,
Class<R> transcodeClass,
boolean isMemoryCacheable,
GlideAnimationFactory<R> animationFactory,
int overrideWidth,
int overrideHeight,
DiskCacheStrategy diskCacheStrategy) {
@SuppressWarnings("unchecked")
GenericRequest<A, T, Z, R> request = (GenericRequest<A, T, Z, R>) REQUEST_POOL.poll();
if (request == null) {
request = new GenericRequest<A, T, Z, R>();
}
request.init(loadProvider,
model,
signature,
context,
priority,
target,
sizeMultiplier,
placeholderDrawable,
placeholderResourceId,
errorDrawable,
errorResourceId,
fallbackDrawable,
fallbackResourceId,
requestListener,
requestCoordinator,
engine,
transformation,
transcodeClass,
isMemoryCacheable,
animationFactory,
overrideWidth,
overrideHeight,
diskCacheStrategy);
return request;
}
private void init(
LoadProvider<A, T, Z, R> loadProvider,
A model,
Key signature,
Context context,
Priority priority,
Target<R> target,
float sizeMultiplier,
Drawable placeholderDrawable,
int placeholderResourceId,
Drawable errorDrawable,
int errorResourceId,
Drawable fallbackDrawable,
int fallbackResourceId,
RequestListener<? super A, R> requestListener,
RequestCoordinator requestCoordinator,
Engine engine,
Transformation<Z> transformation,
Class<R> transcodeClass,
boolean isMemoryCacheable,
GlideAnimationFactory<R> animationFactory,
int overrideWidth,
int overrideHeight,
DiskCacheStrategy diskCacheStrategy) {
this.loadProvider = loadProvider;
this.model = model;
this.signature = signature;
this.fallbackDrawable = fallbackDrawable;
this.fallbackResourceId = fallbackResourceId;
this.context = context.getApplicationContext();
this.priority = priority;
this.target = target;
this.sizeMultiplier = sizeMultiplier;
this.placeholderDrawable = placeholderDrawable;
this.placeholderResourceId = placeholderResourceId;
this.errorDrawable = errorDrawable;
this.errorResourceId = errorResourceId;
this.requestListener = requestListener;
this.requestCoordinator = requestCoordinator;
this.engine = engine;
this.transformation = transformation;
this.transcodeClass = transcodeClass;
this.isMemoryCacheable = isMemoryCacheable;
this.animationFactory = animationFactory;
this.overrideWidth = overrideWidth;
this.overrideHeight = overrideHeight;
this.diskCacheStrategy = diskCacheStrategy;
status = Status.PENDING;
// We allow null models by just setting an error drawable. Null models will always have empty providers, we
// simply skip our sanity checks in that unusual case.
if (model != null) {
check("ModelLoader", loadProvider.getModelLoader(), "try .using(ModelLoader)");
check("Transcoder", loadProvider.getTranscoder(), "try .as*(Class).transcode(ResourceTranscoder)");
check("Transformation", transformation, "try .transform(UnitTransformation.get())");
if (diskCacheStrategy.cacheSource()) {
check("SourceEncoder", loadProvider.getSourceEncoder(),
"try .sourceEncoder(Encoder) or .diskCacheStrategy(NONE/RESULT)");
} else {
check("SourceDecoder", loadProvider.getSourceDecoder(),
"try .decoder/.imageDecoder/.videoDecoder(ResourceDecoder) or .diskCacheStrategy(ALL/SOURCE)");
}
if (diskCacheStrategy.cacheSource() || diskCacheStrategy.cacheResult()) {
// TODO if(resourceClass.isAssignableFrom(InputStream.class) it is possible to wrap sourceDecoder
// and use it instead of cacheDecoder: new FileToStreamDecoder<Z>(sourceDecoder)
// in that case this shouldn't throw
check("CacheDecoder", loadProvider.getCacheDecoder(),
"try .cacheDecoder(ResouceDecoder) or .diskCacheStrategy(NONE)");
}
if (diskCacheStrategy.cacheResult()) {
check("Encoder", loadProvider.getEncoder(),
"try .encode(ResourceEncoder) or .diskCacheStrategy(NONE/SOURCE)");
}
}
}
/**
* Removes the current {@link Transformation}.
*
* @return This request builder.
*/
@SuppressWarnings("unchecked")
public GenericRequestBuilder<ModelType, DataType, ResourceType, TranscodeType> dontTransform() {
Transformation<ResourceType> transformation = UnitTransformation.get();
return transform(transformation);
}
@Override
public boolean encode(Resource<GifDrawable> resource, OutputStream os) {
long startTime = LogTime.getLogTime();
GifDrawable drawable = resource.get();
Transformation<Bitmap> transformation = drawable.getFrameTransformation();
if (transformation instanceof UnitTransformation) {
return writeDataDirect(drawable.getData(), os);
}
GifDecoder decoder = decodeHeaders(drawable.getData());
AnimatedGifEncoder encoder = factory.buildEncoder();
if (!encoder.start(os)) {
return false;
}
for (int i = 0; i < decoder.getFrameCount(); i++) {
Bitmap currentFrame = decoder.getNextFrame();
Resource<Bitmap> transformedResource = getTransformedFrame(currentFrame, transformation, drawable);
try {
if (!encoder.addFrame(transformedResource.get())) {
return false;
}
int currentFrameIndex = decoder.getCurrentFrameIndex();
int delay = decoder.getDelay(currentFrameIndex);
encoder.setDelay(delay);
decoder.advance();
} finally {
transformedResource.recycle();
}
}
boolean result = encoder.finish();
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Log.v(TAG, "Encoded gif with " + decoder.getFrameCount() + " frames and " + drawable.getData().length
+ " bytes in " + LogTime.getElapsedMillis(startTime) + " ms");
}
return result;
}
public GifDrawable(GifDrawable other, Bitmap firstFrame,
Transformation<Bitmap> frameTransformation) {
this(new GifState(other.state.gifHeader, other.state.data, other.state.context,
frameTransformation, other.state.targetWidth, other.state.targetHeight,
other.state.bitmapProvider, other.state.bitmapPool, firstFrame));
}
public Transformation<Bitmap> getFrameTransformation() {
return state.frameTransformation;
}
public GifDrawableTransformation(Transformation<Bitmap> wrapped, BitmapPool bitmapPool) {
this.wrapped = wrapped;
this.bitmapPool = bitmapPool;
}
public GifBitmapWrapperTransformation(BitmapPool bitmapPool, Transformation<Bitmap> bitmapTransformation) {
this(bitmapTransformation, new GifDrawableTransformation(bitmapTransformation, bitmapPool));
}
GifBitmapWrapperTransformation(Transformation<Bitmap> bitmapTransformation,
Transformation<GifDrawable> gifDataTransformation) {
this.bitmapTransformation = bitmapTransformation;
this.gifDataTransformation = gifDataTransformation;
}
public DecodeJob(EngineKey resultKey, int width, int height, DataFetcher<A> fetcher,
DataLoadProvider<A, T> loadProvider, Transformation<T> transformation, ResourceTranscoder<T, Z> transcoder,
DiskCacheProvider diskCacheProvider, DiskCacheStrategy diskCacheStrategy, Priority priority) {
this(resultKey, width, height, fetcher, loadProvider, transformation, transcoder, diskCacheProvider,
diskCacheStrategy, priority, DEFAULT_FILE_OPENER);
}
/**
* Starts a load for the given arguments. Must be called on the main thread.
*
* <p>
* The flow for any request is as follows:
* <ul>
* <li>Check the memory cache and provide the cached resource if present</li>
* <li>Check the current set of actively used resources and return the active resource if present</li>
* <li>Check the current set of in progress loads and add the cb to the in progress load if present</li>
* <li>Start a new load</li>
* </ul>
* </p>
*
* <p>
* Active resources are those that have been provided to at least one request and have not yet been released.
* Once all consumers of a resource have released that resource, the resource then goes to cache. If the
* resource is ever returned to a new consumer from cache, it is re-added to the active resources. If the
* resource is evicted from the cache, its resources are recycled and re-used if possible and the resource is
* discarded. There is no strict requirement that consumers release their resources so active resources are
* held weakly.
* </p>
*
* @param signature A non-null unique key to be mixed into the cache key that identifies the version of the data to
* be loaded.
* @param width The target width in pixels of the desired resource.
* @param height The target height in pixels of the desired resource.
* @param fetcher The fetcher to use to retrieve data not in the disk cache.
* @param loadProvider The load provider containing various encoders and decoders use to decode and encode data.
* @param transformation The transformation to use to transform the decoded resource.
* @param transcoder The transcoder to use to transcode the decoded and transformed resource.
* @param priority The priority with which the request should run.
* @param isMemoryCacheable True if the transcoded resource can be cached in memory.
* @param diskCacheStrategy The strategy to use that determines what type of data, if any,
* will be cached in the local disk cache.
* @param cb The callback that will be called when the load completes.
*
* @param <T> The type of data the resource will be decoded from.
* @param <Z> The type of the resource that will be decoded.
* @param <R> The type of the resource that will be transcoded from the decoded resource.
*/
public <T, Z, R> LoadStatus load(Key signature, int width, int height, DataFetcher<T> fetcher,
DataLoadProvider<T, Z> loadProvider, Transformation<Z> transformation, ResourceTranscoder<Z, R> transcoder,
Priority priority, boolean isMemoryCacheable, DiskCacheStrategy diskCacheStrategy, ResourceCallback cb) {
Util.assertMainThread();
long startTime = LogTime.getLogTime();
final String id = fetcher.getId();
EngineKey key = keyFactory.buildKey(id, signature, width, height, loadProvider.getCacheDecoder(),
loadProvider.getSourceDecoder(), transformation, loadProvider.getEncoder(),
transcoder, loadProvider.getSourceEncoder());
EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
if (cached != null) {
cb.onResourceReady(cached);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Loaded resource from cache", startTime, key);
}
return null;
}
EngineResource<?> active = loadFromActiveResources(key, isMemoryCacheable);
if (active != null) {
cb.onResourceReady(active);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Loaded resource from active resources", startTime, key);
}
return null;
}
EngineJob current = jobs.get(key);
if (current != null) {
current.addCallback(cb);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Added to existing load", startTime, key);
}
return new LoadStatus(cb, current);
}
EngineJob engineJob = engineJobFactory.build(key, isMemoryCacheable);
DecodeJob<T, Z, R> decodeJob = new DecodeJob<T, Z, R>(key, width, height, fetcher, loadProvider, transformation,
transcoder, diskCacheProvider, diskCacheStrategy, priority);
EngineRunnable runnable = new EngineRunnable(engineJob, decodeJob, priority);
jobs.put(key, engineJob);
engineJob.addCallback(cb);
engineJob.start(runnable);
if (Log.isLoggable(TAG, Log.VERBOSE)) {
logWithTimeAndKey("Started new load", startTime, key);
}
return new LoadStatus(cb, engineJob);
}
public Transformation<Bitmap> getTransformation() {
return transformation;
}
public DokitGlideTransform(Object mRequestBuilder, Object transformation) {
this.mRequestBuilder = mRequestBuilder;
if (transformation instanceof Transformation) {
this.mWrap = (Transformation) transformation;
}
}
public static Transformation<Bitmap> transform(Object baseRequestOptions, Object transformation) {
return new DokitGlideTransform(baseRequestOptions, transformation);
}
public Transformation<Bitmap> getBitmapTransformation() {
return bitmapTransformation;
}