extract MultiSourceHelper
Reviewed By: andreicoman11 Differential Revision: D3505224
This commit is contained in:
parent
9a28701bd8
commit
1b77f1a372
|
@ -11,8 +11,8 @@ package com.facebook.react.flat;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
|
@ -31,6 +31,9 @@ import com.facebook.react.bridge.ReadableMap;
|
|||
import com.facebook.react.views.image.ImageLoadEvent;
|
||||
import com.facebook.react.views.image.ImageResizeMode;
|
||||
import com.facebook.react.views.image.ReactImageView;
|
||||
import com.facebook.react.views.imagehelper.ImageSource;
|
||||
import com.facebook.react.views.imagehelper.MultiSourceHelper;
|
||||
import com.facebook.react.views.imagehelper.MultiSourceHelper.MultiSourceResult;
|
||||
|
||||
/**
|
||||
* DrawImageWithDrawee is DrawCommand that can draw a local or remote image.
|
||||
|
@ -39,7 +42,7 @@ import com.facebook.react.views.image.ReactImageView;
|
|||
/* package */ final class DrawImageWithDrawee extends AbstractDrawCommand
|
||||
implements DrawImage, ControllerListener {
|
||||
|
||||
private @Nullable Map<String, Double> mSources;
|
||||
private final List<ImageSource> mSources = new LinkedList<>();
|
||||
private @Nullable Context mContext;
|
||||
private @Nullable DraweeRequestHelper mRequestHelper;
|
||||
private @Nullable PorterDuffColorFilter mColorFilter;
|
||||
|
@ -53,25 +56,25 @@ import com.facebook.react.views.image.ReactImageView;
|
|||
|
||||
@Override
|
||||
public boolean hasImageRequest() {
|
||||
return mSources != null && !mSources.isEmpty();
|
||||
return !mSources.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(Context context, @Nullable ReadableArray sources) {
|
||||
if (mSources == null) {
|
||||
mSources = new HashMap<>();
|
||||
}
|
||||
mSources.clear();
|
||||
if (sources != null && sources.size() != 0) {
|
||||
// Optimize for the case where we have just one uri, case in which we don't need the sizes
|
||||
if (sources.size() == 1) {
|
||||
mSources.put(sources.getMap(0).getString("uri"), 0.0d);
|
||||
ReadableMap source = sources.getMap(0);
|
||||
mSources.add(new ImageSource(context, source.getString("uri")));
|
||||
} else {
|
||||
for (int idx = 0; idx < sources.size(); idx++) {
|
||||
ReadableMap source = sources.getMap(idx);
|
||||
mSources.put(
|
||||
mSources.add(new ImageSource(
|
||||
context,
|
||||
source.getString("uri"),
|
||||
source.getDouble("width") * source.getDouble("height"));
|
||||
source.getDouble("width"),
|
||||
source.getDouble("height")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -227,39 +230,30 @@ import com.facebook.react.views.image.ReactImageView;
|
|||
}
|
||||
|
||||
private void computeRequestHelper() {
|
||||
String[] imageSources = getImageSources();
|
||||
if (imageSources == null) {
|
||||
MultiSourceResult multiSource = MultiSourceHelper.getBestSourceForSize(
|
||||
Math.round(getRight() - getLeft()),
|
||||
Math.round(getBottom() - getTop()),
|
||||
mSources);
|
||||
ImageSource source = multiSource.getBestResult();
|
||||
ImageSource cachedSource = multiSource.getBestResultInCache();
|
||||
if (source == null) {
|
||||
mRequestHelper = null;
|
||||
return;
|
||||
}
|
||||
ImageRequest imageRequest =
|
||||
ImageRequestHelper.createImageRequest(Assertions.assertNotNull(mContext), imageSources[0]);
|
||||
ImageRequest imageRequest = ImageRequestHelper.createImageRequest(
|
||||
Assertions.assertNotNull(mContext),
|
||||
source.getSource());
|
||||
|
||||
ImageRequest cachedImageRequest = null;
|
||||
if (imageSources.length >= 2 && imageSources[1] != null) {
|
||||
if (cachedSource != null) {
|
||||
cachedImageRequest = ImageRequestHelper.createImageRequest(
|
||||
Assertions.assumeNotNull(mContext),
|
||||
imageSources[1]);
|
||||
cachedSource.getSource());
|
||||
}
|
||||
mRequestHelper = new
|
||||
DraweeRequestHelper(Assertions.assertNotNull(imageRequest), cachedImageRequest, this);
|
||||
}
|
||||
|
||||
private @Nullable String[] getImageSources() {
|
||||
if (mSources == null || mSources.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (hasMultipleSources()) {
|
||||
final double targetImageSize = (getRight() - getLeft()) * (getBottom() - getTop());
|
||||
return MultiSourceImageHelper.getImageSourceFromMultipleSources(targetImageSize, mSources);
|
||||
}
|
||||
return new String[]{mSources.keySet().iterator().next()};
|
||||
}
|
||||
|
||||
private boolean hasMultipleSources() {
|
||||
return Assertions.assertNotNull(mSources).size() > 1;
|
||||
}
|
||||
|
||||
private boolean shouldDisplayBorder() {
|
||||
return mBorderColor != 0 || mBorderRadius >= 0.5f;
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@ package com.facebook.react.flat;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
|
@ -32,6 +32,9 @@ import com.facebook.react.bridge.ReadableArray;
|
|||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.views.image.ImageResizeMode;
|
||||
import com.facebook.react.views.image.ReactImageView;
|
||||
import com.facebook.react.views.imagehelper.ImageSource;
|
||||
import com.facebook.react.views.imagehelper.MultiSourceHelper;
|
||||
import com.facebook.react.views.imagehelper.MultiSourceHelper.MultiSourceResult;
|
||||
|
||||
/**
|
||||
* DrawImageWithPipeline is DrawCommand that can draw a local or remote image.
|
||||
|
@ -43,7 +46,7 @@ import com.facebook.react.views.image.ReactImageView;
|
|||
private static final Paint PAINT = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
|
||||
private static final int BORDER_BITMAP_PATH_DIRTY = 1 << 1;
|
||||
|
||||
private @Nullable Map<String, Double> mSources;
|
||||
private final List<ImageSource> mSources = new LinkedList<>();
|
||||
private @Nullable Context mContext;
|
||||
private final Matrix mTransform = new Matrix();
|
||||
private ScaleType mScaleType = ImageResizeMode.defaultValue();
|
||||
|
@ -62,25 +65,25 @@ import com.facebook.react.views.image.ReactImageView;
|
|||
|
||||
@Override
|
||||
public boolean hasImageRequest() {
|
||||
return mSources != null && !mSources.isEmpty();
|
||||
return !mSources.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSource(Context context, @Nullable ReadableArray sources) {
|
||||
if (mSources == null) {
|
||||
mSources = new HashMap<>();
|
||||
}
|
||||
mSources.clear();
|
||||
if (sources != null && sources.size() != 0) {
|
||||
// Optimize for the case where we have just one uri, case in which we don't need the sizes
|
||||
if (sources.size() == 1) {
|
||||
mSources.put(sources.getMap(0).getString("uri"), 0.0d);
|
||||
ReadableMap source = sources.getMap(0);
|
||||
mSources.add(new ImageSource(context, source.getString("uri")));
|
||||
} else {
|
||||
for (int idx = 0; idx < sources.size(); idx++) {
|
||||
ReadableMap source = sources.getMap(idx);
|
||||
mSources.put(
|
||||
mSources.add(new ImageSource(
|
||||
context,
|
||||
source.getString("uri"),
|
||||
source.getDouble("width") * source.getDouble("height"));
|
||||
source.getDouble("width"),
|
||||
source.getDouble("height")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -225,32 +228,23 @@ import com.facebook.react.views.image.ReactImageView;
|
|||
}
|
||||
|
||||
private void computeRequestHelper() {
|
||||
String[] imageSources = getImageSources();
|
||||
if (imageSources == null) {
|
||||
MultiSourceResult multiSource = MultiSourceHelper.getBestSourceForSize(
|
||||
Math.round(getRight() - getLeft()),
|
||||
Math.round(getBottom() - getTop()),
|
||||
mSources);
|
||||
ImageSource source = multiSource.getBestResult();
|
||||
if (source == null) {
|
||||
mRequestHelper = null;
|
||||
return;
|
||||
}
|
||||
ImageRequest imageRequest =
|
||||
ImageRequestHelper.createImageRequest(Assertions.assertNotNull(mContext), imageSources[0]);
|
||||
ImageRequest imageRequest = ImageRequestHelper.createImageRequest(
|
||||
Assertions.assertNotNull(mContext),
|
||||
source.getSource());
|
||||
|
||||
// DrawImageWithPipeline does now support displaying low res cache images before request
|
||||
mRequestHelper = new PipelineRequestHelper(Assertions.assertNotNull(imageRequest));
|
||||
}
|
||||
|
||||
private @Nullable String[] getImageSources() {
|
||||
if (mSources == null || mSources.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
if (hasMultipleSources()) {
|
||||
final double targetImageSize = (getRight() - getLeft()) * (getBottom() - getTop());
|
||||
return MultiSourceImageHelper.getImageSourceFromMultipleSources(targetImageSize, mSources);
|
||||
}
|
||||
return new String[]{mSources.keySet().iterator().next()};
|
||||
}
|
||||
|
||||
private boolean hasMultipleSources() {
|
||||
return Assertions.assertNotNull(mSources).size() > 1;
|
||||
}
|
||||
|
||||
/* package */ void updateBounds(Bitmap bitmap) {
|
||||
Assertions.assumeNotNull(mCallback).invalidate();
|
||||
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
package com.facebook.react.flat;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import com.facebook.imagepipeline.core.ImagePipeline;
|
||||
import com.facebook.imagepipeline.core.ImagePipelineFactory;
|
||||
|
||||
/**
|
||||
* Helper class for computing the source to be used for an Image.
|
||||
*/
|
||||
/* package */ class MultiSourceImageHelper {
|
||||
|
||||
/**
|
||||
* Chooses the image source with the size closest to the target image size. Must be called only
|
||||
* after the layout pass when the sizes of the target image have been computed, and when there
|
||||
* are at least two sources to choose from.
|
||||
*/
|
||||
public static @Nullable String[] getImageSourceFromMultipleSources(
|
||||
double targetImageSize,
|
||||
Map<String, Double> sources) {
|
||||
ImagePipeline imagePipeline = ImagePipelineFactory.getInstance().getImagePipeline();
|
||||
double bestPrecision = Double.MAX_VALUE;
|
||||
double bestCachePrecision = Double.MAX_VALUE;
|
||||
String imageSource = null;
|
||||
String cachedImageSource = null;
|
||||
for (Map.Entry<String, Double> source : sources.entrySet()) {
|
||||
final double precision = Math.abs(1.0 - (source.getValue()) / targetImageSize);
|
||||
if (precision < bestPrecision) {
|
||||
bestPrecision = precision;
|
||||
imageSource = source.getKey();
|
||||
}
|
||||
|
||||
Uri sourceUri = Uri.parse(source.getKey());
|
||||
if (precision < bestCachePrecision &&
|
||||
(imagePipeline.isInBitmapMemoryCache(sourceUri) ||
|
||||
imagePipeline.isInDiskCacheSync(sourceUri))) {
|
||||
bestCachePrecision = precision;
|
||||
cachedImageSource = source.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
// don't use cached image source if it's the same as the image source
|
||||
if (cachedImageSource != null && cachedImageSource.equals(imageSource)) {
|
||||
cachedImageSource = null;
|
||||
}
|
||||
return new String[]{imageSource, cachedImageSource};
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue