react-native-fast-image icon indicating copy to clipboard operation
react-native-fast-image copied to clipboard

Android Image Display Blur

Open Link-Kou opened this issue 5 years ago • 23 comments

Displaying images in ios is not blurred

Blur picture on Android

Link-Kou avatar Apr 03 '19 03:04 Link-Kou

+1

gao520sun avatar Apr 10 '19 02:04 gao520sun

do you guys have any temp solution for this bug?

johnlim5847 avatar May 27 '19 07:05 johnlim5847

Hi @fannaoshaoxiang! Could you please provide screenshots and maybe a code sample to show more about this issue? Thanks!

Ilphrin avatar May 28 '19 14:05 Ilphrin

same here

erennyuksell avatar Jul 02 '19 11:07 erennyuksell

same issue, and i find a solution image

/**
 * Created by kalaliu on 2017/8/25.
 */
import React from 'react'
import _ from 'lodash'
import {Thumbnail} from 'native-base'
import FastImage from 'react-native-fast-image'
import device from '../nice-router/device'

import {
  loadLargeImg,
  loadMiddleImg,
  loadNormalImg,
  loadOriginImg,
  loadServerImage,
  loadSmallImg,
  loadSourceImg,
  loadTinyImg,
  loadWaterfallImg,
  loadXLargeImg,
} from '../utils/image/image-tools'

export default class ServerImage extends React.PureComponent {
  constructor(props, context) {
    super(props, context)
    const {width = '100%', height = '50%'} = this.props
    this.state = {
      width,
      height,
    }
  }

  onLoad = e => {
    const {
      nativeEvent: {width, height},
    } = e
    // console.log('auto resize.onLoad')
    const result = this.getAutoSize(width, height)
    // console.log('auto resize.onLoad,calc result', result)
    this.setState({
      width: result.width,
      height: result.height,
    })
    if (this.props.onLoad) {
      this.props.onLoad(e)
    }
  }

  getAutoSize = (imageWidth, imageHeight) => {
    const {width, height, outlineWidth = 20} = this.props
    const ratio = imageHeight / imageWidth
    let targetWidth = _.isNumber(width) ? width : null
    let targetHeight = _.isNumber(height) ? height : null

    // fitWidth
    if (targetWidth && !targetHeight) {
      targetHeight = targetWidth * ratio
    }
    // fixHeight
    if (!targetWidth && targetHeight) {
      targetWidth = targetHeight / ratio
    }

    // fixConstrain
    if (targetWidth && targetHeight) {
      const constrainRatio = targetHeight / width
      if (ratio > constrainRatio) {
        // 长图
        targetWidth = targetHeight / ratio
      } else {
        targetHeight = targetWidth * ratio
      }
    }
    // 100%
    if (!targetWidth && !targetHeight) {
      targetWidth = device.width - outlineWidth
      targetHeight = targetWidth * ratio
    }

    targetWidth = _.isNumber(targetWidth)
      ? _.toNumber(targetWidth.toFixed(2))
      : targetWidth
    targetHeight = _.isNumber(targetHeight)
      ? _.toNumber(targetHeight.toFixed(2))
      : targetHeight

    // console.log(
    //   'auto resize target',
    //   targetWidth,
    //   targetHeight,
    //   'remote image size',
    //   imageWidth,
    //   imageHeight
    // )
    const result = {
      width: targetWidth,
      height: targetHeight,
    }
    return result
  }

  render() {
    const {
      source,
      size = 'normal',
      thumbnail,
      autoResize,
      ...others
    } = this.props

    let {uri = ''} = source
    if (uri.length === 0) {
      return null
    }
    // source.uri="https://xubai-public.oss-cn-beijing.aliyuncs.com/upload/MoyiUser/MU101354/2018/1026/072552_9293183.4288x2848.jpg"
    switch (size) {
      case 'tiny':
        uri = loadTinyImg(source.uri)
        break
      case 'small':
        uri = loadSmallImg(source.uri)
        break
      case 'middle':
        uri = loadMiddleImg(source.uri)
        break
      case 'normal':
        uri = loadNormalImg(source.uri)
        break
      case 'large':
        uri = loadLargeImg(source.uri)
        break
      case 'xlarge':
        uri = loadXLargeImg(source.uri)
        break
      case 'origin':
        uri = loadOriginImg(source.uri)
        break
      case 'waterfall':
        uri = loadWaterfallImg(source.uri)
        break
      case 'source':
        uri = loadSourceImg(source.uri)
        break
      default:
        uri = loadServerImage(uri)
    }

    if (!uri.startsWith('http')) {
      console.warn(`invalidate image form server-image${uri}`)
      return null
    }

    if (thumbnail) {
      return <Thumbnail {...others} source={{uri}} />
    }

    if (autoResize) {
      const {style, width, height, ...otherProps} = others
      // console.log('auto resize', uri, this.state)
      return (
        <FastImage
          resizeMode={FastImage.resizeMode.contain}
          {...otherProps}
          style={{
            ...style,
            width: this.state.width,
            height: this.state.height,
            alignSelf: 'center',
          }}
          onLoad={this.onLoad}
          source={{uri}}
        />
      )
    }

    return <FastImage {...others} source={{uri}} />
  }
}

log here

 some blur issue {width: 330, height: "50%"}
 some blur issue {width: 330, height: 1248.65}

solution: remove default value of height

  constructor(props, context) {
    super(props, context)
    const {width = '100%', height = '50%'} = this.props
 ....
  }

to

constructor(props, context) {
    super(props, context)
    const {width = '100%', height } = this.props
 ....
  }

log here

some blur issue {width: 330, height: undefined}
some blur issue {width: 330, height: 1252.17}

kala888 avatar Jul 26 '19 05:07 kala888

+1

hanwenbo avatar Jul 27 '19 04:07 hanwenbo

My solution is to set the default height to "auto"

hanwenbo avatar Jul 27 '19 04:07 hanwenbo

+1

meiqi1992 avatar Sep 17 '20 02:09 meiqi1992

any solutions for this problem?

iKoru avatar Dec 02 '20 13:12 iKoru

+1

zyestin avatar Dec 31 '20 15:12 zyestin

My solution is to set the default height to "auto"

Could you please show us the code?

zyestin avatar Dec 31 '20 15:12 zyestin

+1

wheelswang avatar Jan 31 '21 17:01 wheelswang

<FastImage source={ source.uri ? {...source, priority: FastImage.priority.high} : source } style={style} />

0xleeaki avatar Feb 19 '21 06:02 0xleeaki

I resolved blurry images on Android by adding .dontTransform() to the Glide builder: https://github.com/DylanVann/react-native-fast-image/blob/0439f7190f141e51a391c84890cdd8a7067c6ad3/android/src/main/java/com/dylanvann/fastimage/FastImageViewManager.java#L99

if (requestManager != null) {
            requestManager
                    // This will make this work for remote and local images. e.g.
                    //    - file:///
                    //    - content://
                    //    - res:/
                    //    - android.resource://
                    //    - data:image/png;base64
                    .load(imageSource.getSourceForLoad())
                    .dontTransform()
                    .apply(FastImageViewConverter.getOptions(context, imageSource, source))
                    .listener(new FastImageRequestListener(key))
                    .into(view);
        }
    }

Seems that image was downscaled by Glide after downloading it.

Hope this helps you all!

yurik94 avatar May 14 '21 14:05 yurik94

i having same issue Images blur on android but its working fine on IOS

ahtisham09 avatar May 28 '21 18:05 ahtisham09

image is work

raymenchow avatar Jul 05 '21 06:07 raymenchow

Is there any update on this????

pateljoel avatar Dec 04 '21 15:12 pateljoel

I resolved blurry images on Android by adding .dontTransform() to the Glide builder:

https://github.com/DylanVann/react-native-fast-image/blob/0439f7190f141e51a391c84890cdd8a7067c6ad3/android/src/main/java/com/dylanvann/fastimage/FastImageViewManager.java#L99

if (requestManager != null) {
            requestManager
                    // This will make this work for remote and local images. e.g.
                    //    - file:///
                    //    - content://
                    //    - res:/
                    //    - android.resource://
                    //    - data:image/png;base64
                    .load(imageSource.getSourceForLoad())
                    .dontTransform()
                    .apply(FastImageViewConverter.getOptions(context, imageSource, source))
                    .listener(new FastImageRequestListener(key))
                    .into(view);
        }
    }

Seems that image was downscaled by Glide after downloading it.

Hope this helps you all!

This worked for me, are there any implications to making this change (performance, etc)?

thame avatar Jan 07 '22 22:01 thame

The change above seems to cause a significant memory leak on Android.

thame avatar Jan 16 '22 18:01 thame

It happens to us if we calculate height and width dynamically. It does not happen on fixed height and width.

  • on first load, the small image is loaded and displayed (i guess the small size ist scaled to final container size and this causes the "bluriness")
  • later the image is not reloaded/redrawn and used from cache even if the container size changed.

Try to render not before you have the final sizes. This worked for us.

Hope this helps.

Happens only on Android devices.

sven09 avatar Jul 07 '22 16:07 sven09

Outer layer add View tag just like<View><FastImage /></View>

BAEBAEWANGD avatar Jul 26 '22 09:07 BAEBAEWANGD

@BAEBAEWANGD Wonderful!

gajjartejas avatar Jul 27 '22 09:07 gajjartejas

Any fix available in 2022 ?

BubbleTrouble14 avatar Dec 25 '22 12:12 BubbleTrouble14

FastImage.cacheControl.immutable is work for me image

hezhengjian avatar Dec 05 '23 10:12 hezhengjian