Enable developers to force Fresco to resize an image
Summary: Here's a little background. Resizing is inferior to scaling. See http://frescolib.org/docs/resizing-rotating.html#_ Currently, React Native has a heuristic to use resize when the image is likely to be from the device's camera. However, there may be other cases where a developer wants to use resize. For example, when the developer knows they'll be downloading a large image from a service but the image will be rendered at a small size on the device. This change adds a `resizeMethod` prop to the `Image` component so developers can choose how Fresco resizes the image. The options are 'auto', 'resize', or 'scale'. When 'auto' is specified, a heuristic is used to choose between 'resize' and 'scale'. The default value is 'auto'. **Test plan (required)** In a small test app, verified that the `resizeMethod` prop properly influences the mechanism that is used to resize the image (e.g. resize or scale). Adam Comella Microsoft Corp. Closes https://github.com/facebook/react-native/pull/9652 Differential Revision: D3841322 Pulled By: foghina fbshipit-source-id: 6c78b5c75ea73053aa10386afd4cbff45f5b8ffe
This commit is contained in:
parent
ea5b335351
commit
b6735f3391
|
@ -65,6 +65,7 @@ function generateRequestId() {
|
|||
var ImageViewAttributes = merge(ReactNativeViewAttributes.UIView, {
|
||||
src: true,
|
||||
loadingIndicatorSrc: true,
|
||||
resizeMethod: true,
|
||||
resizeMode: true,
|
||||
progressiveRenderingEnabled: true,
|
||||
fadeDuration: true,
|
||||
|
@ -130,6 +131,26 @@ var Image = React.createClass({
|
|||
* Used to locate this view in end-to-end tests.
|
||||
*/
|
||||
testID: PropTypes.string,
|
||||
/**
|
||||
* The mechanism that should be used to resize the image when the image's dimensions
|
||||
* differ from the image view's dimensions. Defaults to `auto`.
|
||||
*
|
||||
* - `auto`: Use heuristics to pick between `resize` and `scale`.
|
||||
*
|
||||
* - `resize`: A software operation which changes the encoded image in memory before it
|
||||
* gets decoded. This should be used instead of `scale` when the image is much larger
|
||||
* than the view.
|
||||
*
|
||||
* - `scale`: The image gets drawn downscaled or upscaled. Compared to `resize`, `scale` is
|
||||
* faster (usually hardware accelerated) and produces higher quality images. This
|
||||
* should be used if the image is smaller than the view. It should also be used if the
|
||||
* image is slightly bigger than the view.
|
||||
*
|
||||
* More details about `resize` and `scale` can be found at http://frescolib.org/docs/resizing-rotating.html.
|
||||
*
|
||||
* @platform android
|
||||
*/
|
||||
resizeMethod: PropTypes.oneOf(['auto', 'resize', 'scale']),
|
||||
/**
|
||||
* Determines how to resize the image when the frame doesn't match the raw
|
||||
* image dimensions.
|
||||
|
|
|
@ -192,6 +192,26 @@ const Image = React.createClass({
|
|||
* @platform ios
|
||||
*/
|
||||
capInsets: EdgeInsetsPropType,
|
||||
/**
|
||||
* The mechanism that should be used to resize the image when the image's dimensions
|
||||
* differ from the image view's dimensions. Defaults to `auto`.
|
||||
*
|
||||
* - `auto`: Use heuristics to pick between `resize` and `scale`.
|
||||
*
|
||||
* - `resize`: A software operation which changes the encoded image in memory before it
|
||||
* gets decoded. This should be used instead of `scale` when the image is much larger
|
||||
* than the view.
|
||||
*
|
||||
* - `scale`: The image gets drawn downscaled or upscaled. Compared to `resize`, `scale` is
|
||||
* faster (usually hardware accelerated) and produces higher quality images. This
|
||||
* should be used if the image is smaller than the view. It should also be used if the
|
||||
* image is slightly bigger than the view.
|
||||
*
|
||||
* More details about `resize` and `scale` can be found at http://frescolib.org/docs/resizing-rotating.html.
|
||||
*
|
||||
* @platform android
|
||||
*/
|
||||
resizeMethod: PropTypes.oneOf(['auto', 'resize', 'scale']),
|
||||
/**
|
||||
* Determines how to resize the image when the frame doesn't match the raw
|
||||
* image dimensions.
|
||||
|
|
|
@ -78,6 +78,7 @@ public class ViewProps {
|
|||
public static final String ELLIPSIZE_MODE = "ellipsizeMode";
|
||||
public static final String ON = "on";
|
||||
public static final String RESIZE_MODE = "resizeMode";
|
||||
public static final String RESIZE_METHOD = "resizeMethod";
|
||||
public static final String TEXT_ALIGN = "textAlign";
|
||||
public static final String TEXT_ALIGN_VERTICAL = "textAlignVertical";
|
||||
public static final String TEXT_DECORATION_LINE = "textDecorationLine";
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* 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.views.image;
|
||||
|
||||
public enum ImageResizeMethod {
|
||||
AUTO,
|
||||
RESIZE,
|
||||
SCALE
|
||||
}
|
|
@ -19,6 +19,7 @@ import android.graphics.PorterDuff.Mode;
|
|||
import com.facebook.csslayout.CSSConstants;
|
||||
import com.facebook.drawee.backends.pipeline.Fresco;
|
||||
import com.facebook.drawee.controller.AbstractDraweeControllerBuilder;
|
||||
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.common.MapBuilder;
|
||||
import com.facebook.react.uimanager.PixelUtil;
|
||||
|
@ -131,6 +132,19 @@ public class ReactImageManager extends SimpleViewManager<ReactImageView> {
|
|||
view.setScaleType(ImageResizeMode.toScaleType(resizeMode));
|
||||
}
|
||||
|
||||
@ReactProp(name = ViewProps.RESIZE_METHOD)
|
||||
public void setResizeMethod(ReactImageView view, @Nullable String resizeMethod) {
|
||||
if (resizeMethod == null || "auto".equals(resizeMethod)) {
|
||||
view.setResizeMethod(ImageResizeMethod.AUTO);
|
||||
} else if ("resize".equals(resizeMethod)) {
|
||||
view.setResizeMethod(ImageResizeMethod.RESIZE);
|
||||
} else if ("scale".equals(resizeMethod)) {
|
||||
view.setResizeMethod(ImageResizeMethod.SCALE);
|
||||
} else {
|
||||
throw new JSApplicationIllegalArgumentException("Invalid resize method: '" + resizeMethod+ "'");
|
||||
}
|
||||
}
|
||||
|
||||
@ReactProp(name = "tintColor", customType = "Color")
|
||||
public void setTintColor(ReactImageView view, @Nullable Integer tintColor) {
|
||||
if (tintColor == null) {
|
||||
|
|
|
@ -82,6 +82,7 @@ public class ReactImageView extends GenericDraweeView {
|
|||
*/
|
||||
private static final Matrix sMatrix = new Matrix();
|
||||
private static final Matrix sInverse = new Matrix();
|
||||
private ImageResizeMethod mResizeMethod = ImageResizeMethod.AUTO;
|
||||
|
||||
private class RoundedCornerPostprocessor extends BasePostprocessor {
|
||||
|
||||
|
@ -260,6 +261,11 @@ public class ReactImageView extends GenericDraweeView {
|
|||
mIsDirty = true;
|
||||
}
|
||||
|
||||
public void setResizeMethod(ImageResizeMethod resizeMethod) {
|
||||
mResizeMethod = resizeMethod;
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
public void setSource(@Nullable ReadableArray sources) {
|
||||
mSources.clear();
|
||||
if (sources != null && sources.size() != 0) {
|
||||
|
@ -451,12 +457,18 @@ public class ReactImageView extends GenericDraweeView {
|
|||
mImageSource = mSources.get(0);
|
||||
}
|
||||
|
||||
private static boolean shouldResize(ImageSource imageSource) {
|
||||
private boolean shouldResize(ImageSource imageSource) {
|
||||
// Resizing is inferior to scaling. See http://frescolib.org/docs/resizing-rotating.html#_
|
||||
// We resize here only for images likely to be from the device's camera, where the app developer
|
||||
// has no control over the original size
|
||||
return
|
||||
UriUtil.isLocalContentUri(imageSource.getUri()) ||
|
||||
UriUtil.isLocalFileUri(imageSource.getUri());
|
||||
if (mResizeMethod == ImageResizeMethod.AUTO) {
|
||||
return
|
||||
UriUtil.isLocalContentUri(imageSource.getUri()) ||
|
||||
UriUtil.isLocalFileUri(imageSource.getUri());
|
||||
} else if (mResizeMethod == ImageResizeMethod.RESIZE) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue