Add Image#getSize for Android

Summary:
I've implemented the getSize method on Image for Android.

**Test plan (required)**

The result in the UIExample app can be seen here:

![android-getsize](https://cloud.githubusercontent.com/assets/570297/15442613/a29c9178-1ee2-11e6-97df-adc20aad0c32.jpg)
Closes https://github.com/facebook/react-native/pull/7664

Differential Revision: D3331704

fbshipit-source-id: d784c861cbc653cd6b49310f4b5516c6583486ca
This commit is contained in:
Corné Dorrestijn 2016-05-20 18:40:59 -07:00 committed by Facebook Github Bot 1
parent fb5d0ff587
commit c1558bc7db
3 changed files with 79 additions and 1 deletions

View File

@ -509,7 +509,6 @@ exports.examples = [
render: function() {
return <ImageSizeExample source={fullImage} />;
},
platform: 'ios',
},
];

View File

@ -113,6 +113,21 @@ var Image = React.createClass({
statics: {
resizeMode: ImageResizeMode,
getSize(
url: string,
success: (width: number, height: number) => void,
failure: (error: any) => void,
) {
return ImageLoader.getSize(url)
.then(function(sizes) {
success(sizes.width, sizes.height);
})
.catch(failure || function() {
console.warn('Failed to get size for image: ' + url);
});
},
/**
* Prefetches a remote image for later use by downloading it to the disk
* cache

View File

@ -11,11 +11,16 @@ package com.facebook.react.modules.image;
import android.net.Uri;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.WritableMap;
import com.facebook.common.executors.CallerThreadExecutor;
import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.BaseDataSubscriber;
import com.facebook.datasource.DataSource;
import com.facebook.datasource.DataSubscriber;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;
import com.facebook.react.bridge.Promise;
@ -27,6 +32,7 @@ public class ImageLoaderModule extends ReactContextBaseJavaModule {
private static final String ERROR_INVALID_URI = "E_INVALID_URI";
private static final String ERROR_PREFETCH_FAILURE = "E_PREFETCH_FAILURE";
private static final String ERROR_GET_SIZE_FAILURE = "E_GET_SIZE_FAILURE";
private final Object mCallerContext;
@ -45,6 +51,64 @@ public class ImageLoaderModule extends ReactContextBaseJavaModule {
return "ImageLoader";
}
@ReactMethod
public void getSize(
String uriString,
final Promise promise) {
if (uriString == null || uriString.isEmpty()) {
promise.reject(ERROR_INVALID_URI, "Cannot get the size of an image for an empty URI");
return;
}
Uri uri = Uri.parse(uriString);
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri).build();
DataSource<CloseableReference<CloseableImage>> dataSource =
Fresco.getImagePipeline().fetchDecodedImage(request, mCallerContext);
DataSubscriber<CloseableReference<CloseableImage>> dataSubscriber =
new BaseDataSubscriber<CloseableReference<CloseableImage>>() {
@Override
protected void onNewResultImpl(
DataSource<CloseableReference<CloseableImage>> dataSource) {
if (!dataSource.isFinished()) {
return;
}
CloseableReference<CloseableImage> ref = dataSource.getResult();
if (ref != null) {
try {
CloseableImage image = ref.get();
WritableMap sizes = Arguments.createMap();
sizes.putInt("width", image.getWidth());
sizes.putInt("height", image.getHeight());
image.close();
promise.resolve(sizes);
} catch (Exception e) {
promise.reject(ERROR_GET_SIZE_FAILURE, e);
} finally {
CloseableReference.closeSafely(ref);
dataSource.close();
}
} else {
dataSource.close();
promise.reject(ERROR_GET_SIZE_FAILURE);
}
}
@Override
protected void onFailureImpl(DataSource<CloseableReference<CloseableImage>> dataSource) {
try {
promise.reject(ERROR_GET_SIZE_FAILURE, dataSource.getFailureCause());
} finally {
dataSource.close();
}
}
};
dataSource.subscribe(dataSubscriber, CallerThreadExecutor.getInstance());
}
/**
* Prefetches the given image to the Fresco image disk cache.
*