@@ -10,14 +10,15 @@ package com.facebook.react.modules.image
1010import android.net.Uri
1111import android.util.SparseArray
1212import com.facebook.common.executors.CallerThreadExecutor
13+ import com.facebook.common.memory.PooledByteBuffer
1314import com.facebook.common.references.CloseableReference
1415import com.facebook.datasource.BaseDataSubscriber
1516import com.facebook.datasource.DataSource
1617import com.facebook.datasource.DataSubscriber
1718import com.facebook.drawee.backends.pipeline.Fresco
1819import com.facebook.fbreact.specs.NativeImageLoaderAndroidSpec
1920import com.facebook.imagepipeline.core.ImagePipeline
20- import com.facebook.imagepipeline.image.CloseableImage
21+ import com.facebook.imagepipeline.image.EncodedImage
2122import com.facebook.imagepipeline.request.ImageRequest
2223import com.facebook.imagepipeline.request.ImageRequestBuilder
2324import com.facebook.react.bridge.GuardedAsyncTask
@@ -83,38 +84,9 @@ internal class ImageLoaderModule : NativeImageLoaderAndroidSpec, LifecycleEventL
8384 }
8485 val source = ImageSource (reactApplicationContext, uriString)
8586 val request: ImageRequest = ImageRequestBuilder .newBuilderWithSource(source.uri).build()
86- val dataSource: DataSource <CloseableReference <CloseableImage >> =
87- this .imagePipeline.fetchDecodedImage(request, this .callerContext)
88- val dataSubscriber: DataSubscriber <CloseableReference <CloseableImage >> =
89- object : BaseDataSubscriber <CloseableReference <CloseableImage >>() {
90- override fun onNewResultImpl (dataSource : DataSource <CloseableReference <CloseableImage >>) {
91- if (! dataSource.isFinished) {
92- return
93- }
94- val ref = dataSource.result
95- if (ref != null ) {
96- try {
97- val image: CloseableImage = ref.get()
98- val sizes = buildReadableMap {
99- put(" width" , image.width)
100- put(" height" , image.height)
101- }
102- promise.resolve(sizes)
103- } catch (e: Exception ) {
104- promise.reject(ERROR_GET_SIZE_FAILURE , e)
105- } finally {
106- CloseableReference .closeSafely(ref)
107- }
108- } else {
109- promise.reject(ERROR_GET_SIZE_FAILURE , " Failed to get the size of the image" )
110- }
111- }
112-
113- override fun onFailureImpl (dataSource : DataSource <CloseableReference <CloseableImage >>) {
114- promise.reject(ERROR_GET_SIZE_FAILURE , dataSource.failureCause)
115- }
116- }
117- dataSource.subscribe(dataSubscriber, CallerThreadExecutor .getInstance())
87+ val dataSource: DataSource <CloseableReference <PooledByteBuffer >> =
88+ this .imagePipeline.fetchEncodedImage(request, this .callerContext)
89+ dataSource.subscribe(createSizeSubscriber(promise), CallerThreadExecutor .getInstance())
11890 }
11991
12092 /* *
@@ -136,39 +108,53 @@ internal class ImageLoaderModule : NativeImageLoaderAndroidSpec, LifecycleEventL
136108 ImageRequestBuilder .newBuilderWithSource(source.uri)
137109 val request: ImageRequest =
138110 ReactNetworkImageRequest .fromBuilderWithHeaders(imageRequestBuilder, headers)
139- val dataSource: DataSource <CloseableReference <CloseableImage >> =
140- this .imagePipeline.fetchDecodedImage(request, this .callerContext)
141- val dataSubscriber: DataSubscriber <CloseableReference <CloseableImage >> =
142- object : BaseDataSubscriber <CloseableReference <CloseableImage >>() {
143- override fun onNewResultImpl (dataSource : DataSource <CloseableReference <CloseableImage >>) {
144- if (! dataSource.isFinished) {
145- return
146- }
147- val ref = dataSource.result
148- if (ref != null ) {
149- try {
150- val image: CloseableImage = ref.get()
151- val sizes = buildReadableMap {
152- put(" width" , image.width)
153- put(" height" , image.height)
154- }
155- promise.resolve(sizes)
156- } catch (e: Exception ) {
157- promise.reject(ERROR_GET_SIZE_FAILURE , e)
158- } finally {
159- CloseableReference .closeSafely(ref)
111+ val dataSource: DataSource <CloseableReference <PooledByteBuffer >> =
112+ this .imagePipeline.fetchEncodedImage(request, this .callerContext)
113+ dataSource.subscribe(createSizeSubscriber(promise), CallerThreadExecutor .getInstance())
114+ }
115+
116+ private fun createSizeSubscriber (
117+ promise : Promise
118+ ): DataSubscriber <CloseableReference <PooledByteBuffer >> =
119+ object : BaseDataSubscriber <CloseableReference <PooledByteBuffer >>() {
120+ override fun onNewResultImpl (dataSource : DataSource <CloseableReference <PooledByteBuffer >>) {
121+ if (! dataSource.isFinished) {
122+ return
123+ }
124+ val ref = dataSource.result
125+ if (ref != null ) {
126+ var encodedImage: EncodedImage ? = null
127+ try {
128+ encodedImage = EncodedImage (ref)
129+ // Swap width and height when the image is rotated 90 or 270 degrees so the
130+ // values reflect the visible dimensions, matching iOS behavior.
131+ val rotated = encodedImage.rotationAngle == 90 || encodedImage.rotationAngle == 270
132+ val width = if (rotated) encodedImage.height else encodedImage.width
133+ val height = if (rotated) encodedImage.width else encodedImage.height
134+ if (width < 0 || height < 0 ) {
135+ promise.reject(ERROR_GET_SIZE_FAILURE , " Failed to get the size of the image" )
136+ return
137+ }
138+ val sizes = buildReadableMap {
139+ put(" width" , width)
140+ put(" height" , height)
160141 }
161- } else {
162- promise.reject(ERROR_GET_SIZE_FAILURE , " Failed to get the size of the image" )
142+ promise.resolve(sizes)
143+ } catch (e: Exception ) {
144+ promise.reject(ERROR_GET_SIZE_FAILURE , e)
145+ } finally {
146+ encodedImage?.close()
147+ CloseableReference .closeSafely(ref)
163148 }
149+ } else {
150+ promise.reject(ERROR_GET_SIZE_FAILURE , " Failed to get the size of the image" )
164151 }
152+ }
165153
166- override fun onFailureImpl (dataSource : DataSource <CloseableReference <CloseableImage >>) {
167- promise.reject(ERROR_GET_SIZE_FAILURE , dataSource.failureCause)
168- }
154+ override fun onFailureImpl (dataSource : DataSource <CloseableReference <PooledByteBuffer >>) {
155+ promise.reject(ERROR_GET_SIZE_FAILURE , dataSource.failureCause)
169156 }
170- dataSource.subscribe(dataSubscriber, CallerThreadExecutor .getInstance())
171- }
157+ }
172158
173159 /* *
174160 * Prefetches the given image to the Fresco image disk cache.
0 commit comments