diff --git a/Examples/UIExplorer/js/ImageExample.js b/Examples/UIExplorer/js/ImageExample.js index 04f7437f807..95ed82f307b 100644 --- a/Examples/UIExplorer/js/ImageExample.js +++ b/Examples/UIExplorer/js/ImageExample.js @@ -677,6 +677,45 @@ exports.examples = [ }, platform: 'ios', }, + { + title: 'Blur Radius', + render: function() { + return ( + + + + + + + + + ); + }, + }, ]; var fullImage = {uri: 'https://facebook.github.io/react/img/logo_og.png'}; diff --git a/Libraries/Image/Image.android.js b/Libraries/Image/Image.android.js index b0e813b3fd8..7d4a7752d3b 100644 --- a/Libraries/Image/Image.android.js +++ b/Libraries/Image/Image.android.js @@ -11,23 +11,24 @@ */ 'use strict'; -var NativeMethodsMixin = require('NativeMethodsMixin'); -var NativeModules = require('NativeModules'); var ImageResizeMode = require('ImageResizeMode'); var ImageStylePropTypes = require('ImageStylePropTypes'); -var ViewStylePropTypes = require('ViewStylePropTypes'); +var NativeMethodsMixin = require('NativeMethodsMixin'); +var NativeModules = require('NativeModules'); +var PropTypes = require('react/lib/ReactPropTypes'); var React = require('React'); var ReactNativeViewAttributes = require('ReactNativeViewAttributes'); +var Set = require('Set'); var StyleSheet = require('StyleSheet'); var StyleSheetPropType = require('StyleSheetPropType'); var View = require('View'); +var ViewStylePropTypes = require('ViewStylePropTypes'); +var filterObject = require('fbjs/lib/filterObject'); var flattenStyle = require('flattenStyle'); var merge = require('merge'); var requireNativeComponent = require('requireNativeComponent'); var resolveAssetSource = require('resolveAssetSource'); -var Set = require('Set'); -var filterObject = require('fbjs/lib/filterObject'); var PropTypes = React.PropTypes; var { @@ -106,6 +107,10 @@ var Image = React.createClass({ height: PropTypes.number, })) ]), + /** + * blurRadius: the blur radius of the blur filter added to the image + */ + blurRadius: PropTypes.number, /** * similarly to `source`, this property represents the resource used to render * the loading indicator for the image, displayed until image is ready to be diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java index 2d5702389ea..78813eefa8b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java @@ -82,6 +82,11 @@ public class ReactImageManager extends SimpleViewManager { view.setSource(sources); } + @ReactProp(name = "blurRadius") + public void setBlurRadius(ReactImageView view, float blurRadius) { + view.setBlurRadius(blurRadius); + } + // In JS this is Image.props.loadingIndicatorSource.uri @ReactProp(name = "loadingIndicatorSrc") public void setLoadingIndicatorSource(ReactImageView view, @Nullable String source) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java index e039a323a8a..259f177f07a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java @@ -46,6 +46,7 @@ import com.facebook.drawee.generic.RoundingParams; import com.facebook.drawee.view.GenericDraweeView; import com.facebook.imagepipeline.common.ResizeOptions; import com.facebook.imagepipeline.image.ImageInfo; +import com.facebook.imagepipeline.postprocessors.IterativeBoxBlurPostProcessor; import com.facebook.imagepipeline.request.BasePostprocessor; import com.facebook.imagepipeline.request.ImageRequest; import com.facebook.imagepipeline.request.ImageRequestBuilder; @@ -159,6 +160,7 @@ public class ReactImageView extends GenericDraweeView { private boolean mIsDirty; private final AbstractDraweeControllerBuilder mDraweeControllerBuilder; private final RoundedCornerPostprocessor mRoundedCornerPostprocessor; + private @Nullable IterativeBoxBlurPostProcessor mIterativeBoxBlurPostProcessor; private @Nullable ControllerListener mControllerListener; private @Nullable ControllerListener mControllerForTesting; private final @Nullable Object mCallerContext; @@ -226,6 +228,16 @@ public class ReactImageView extends GenericDraweeView { mIsDirty = true; } + public void setBlurRadius(float blurRadius) { + if (blurRadius == 0) { + mIterativeBoxBlurPostProcessor = null; + } else { + mIterativeBoxBlurPostProcessor = + new IterativeBoxBlurPostProcessor((int) PixelUtil.toPixelFromDIP(blurRadius)); + } + mIsDirty = true; + } + public void setBorderColor(int borderColor) { mBorderColor = borderColor; mIsDirty = true; @@ -326,7 +338,7 @@ public class ReactImageView extends GenericDraweeView { computedCorners[2] = mBorderCornerRadii != null && !YogaConstants.isUndefined(mBorderCornerRadii[2]) ? mBorderCornerRadii[2] : defaultBorderRadius; computedCorners[3] = mBorderCornerRadii != null && !YogaConstants.isUndefined(mBorderCornerRadii[3]) ? mBorderCornerRadii[3] : defaultBorderRadius; } - + public void setHeaders(ReadableMap headers) { mHeaders = headers; } @@ -386,7 +398,13 @@ public class ReactImageView extends GenericDraweeView { ? mFadeDurationMs : mImageSource.isResource() ? 0 : REMOTE_IMAGE_FADE_DURATION_MS); - Postprocessor postprocessor = usePostprocessorScaling ? mRoundedCornerPostprocessor : null; + // TODO: t13601664 Support multiple PostProcessors + Postprocessor postprocessor = null; + if (usePostprocessorScaling) { + postprocessor = mRoundedCornerPostprocessor; + } else if (mIterativeBoxBlurPostProcessor != null) { + postprocessor = mIterativeBoxBlurPostProcessor; + } ResizeOptions resizeOptions = doResize ? new ResizeOptions(getWidth(), getHeight()) : null;