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;