@@ -29,15 +29,23 @@ import {
2929 View ,
3030} from 'react-native' ;
3131
32+ const ALPHA_PNG_ASSET = require ( '../../assets/alpha-hotdog.png' ) ;
33+
3234const IMAGE1 =
3335 'https://www.facebook.com/assets/fb_lite_messaging/E2EE-settings@3x.png' ;
3436const IMAGE2 =
3537 'https://www.facebook.com/ar_effect/external_textures/648609739826677.png' ;
36-
3738const base64Icon =
3839 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEsAAABLCAQAAACSR7JhAAADtUlEQVR4Ac3YA2Bj6QLH0XPT1Fzbtm29tW3btm3bfLZtv7e2ObZnms7d8Uw098tuetPzrxv8wiISrtVudrG2JXQZ4VOv+qUfmqCGGl1mqLhoA52oZlb0mrjsnhKpgeUNEs91Z0pd1kvihA3ULGVHiQO2narKSHKkEMulm9VgUyE60s1aWoMQUbpZOWE+kaqs4eLEjdIlZTcFZB0ndc1+lhB1lZrIuk5P2aib1NBpZaL+JaOGIt0ls47SKzLC7CqrlGF6RZ09HGoNy1lYl2aRSWL5GuzqWU1KafRdoRp0iOQEiDzgZPnG6DbldcomadViflnl/cL93tOoVbsOLVM2jylvdWjXolWX1hmfZbGR/wjypDjFLSZIRov09BgYmtUqPQPlQrPapecLgTIy0jMgPKtTeob2zWtrGH3xvjUkPCtNg/tm1rjwrMa+mdUkPd3hWbH0jArPGiU9ufCsNNWFZ40wpwn+62/66R2RUtoso1OB34tnLOcy7YB1fUdc9e0q3yru8PGM773vXsuZ5YIZX+5xmHwHGVvlrGPN6ZSiP1smOsMMde40wKv2VmwPPVXNut4sVpUreZiLBHi0qln/VQeI/LTMYXpsJtFiclUN+5HVZazim+Ky+7sAvxWnvjXrJFneVtLWLyPJu9K3cXLWeOlbMTlrIelbMDlrLenrjEQOtIF+fuI9xRp9ZBFp6+b6WT8RrxEpdK64BuvHgDk+vUy+b5hYk6zfyfs051gRoNO1usU12WWRWL73/MMEy9pMi9qIrR4ZpV16Rrvduxazmy1FSvuFXRkqTnE7m2kdb5U8xGjLw/spRr1uTov4uOgQE+0N/DvFrG/Jt7i/FzwxbA9kDanhf2w+t4V97G8lrT7wc08aA2QNUkuTfW/KimT01wdlfK4yEw030VfT0RtZbzjeMprNq8m8tnSTASrTLti64oBNdpmMQm0eEwvfPwRbUBywG5TzjPCsdwk3IeAXjQblLCoXnDVeoAz6SfJNk5TTzytCNZk/POtTSV40NwOFWzw86wNJRpubpXsn60NJFlHeqlYRbslqZm2jnEZ3qcSKgm0kTli3zZVS7y/iivZTweYXJ26Y+RTbV1zh3hYkgyFGSTKPfRVbRqWWVReaxYeSLarYv1Qqsmh1s95S7G+eEWK0f3jYKTbV6bOwepjfhtafsvUsqrQvrGC8YhmnO9cSCk3yuY984F1vesdHYhWJ5FvASlacshUsajFt2mUM9pqzvKGcyNJW0arTKN1GGGzQlH0tXwLDgQTurS8eIQAAAABJRU5ErkJggg==' ;
3940const IMAGE_PREFETCH_URL = `${ IMAGE1 } ?r=1&t=${ Date . now ( ) } ` ;
4041const prefetchTask = Image . prefetch ( IMAGE_PREFETCH_URL ) ;
42+ // Remote JPEG (RN OSS test fixture) used by the progressive example. Trusted by
43+ // the API 24 Android CI emulator and reachable on both platforms.
44+ const LARGE_JPEG =
45+ 'https://www.facebook.com/assets/react_native_oss_tests/large-image@1x.jpg' ;
46+ // Display-P3 wide-gamut sample (WebKit color-gamut test image).
47+ const WIDE_GAMUT_P3_URL =
48+ 'https://webkit.org/blog-files/color-gamut/Webkit-logo-P3.png' ;
4149
4250type ImageSource = Readonly < {
4351 uri : string ,
@@ -845,6 +853,142 @@ function ImageGetSizePlatformTest(props: PlatformTestComponentBaseProps) {
845853 ) ;
846854}
847855
856+ function ProgressiveJpegExample ( ) : React . Node {
857+ const [ loadStarted , setLoadStarted ] = useState ( false ) ;
858+ const [ progress , setProgress ] = useState < ?number > ( null ) ;
859+ const [ loaded , setLoaded ] = useState ( false ) ;
860+ const [ uri ] = useState ( ( ) => `${ LARGE_JPEG } ?progressive=${ Date . now ( ) } ` ) ;
861+ return (
862+ < View testID = "image-progressive-jpeg" >
863+ < Image
864+ testID = "progressive-jpeg-image"
865+ style = { styles . base }
866+ source = { { uri} }
867+ progressiveRenderingEnabled = { true }
868+ onLoadStart = { ( ) => setLoadStarted ( true ) }
869+ onProgress = { event => {
870+ const { loaded : bytesLoaded , total} = event . nativeEvent ;
871+ if ( total > 0 ) {
872+ setProgress ( Math . round ( ( bytesLoaded / total ) * 100 ) ) ;
873+ }
874+ } }
875+ onLoad = { ( ) => setLoaded ( true ) }
876+ />
877+ { loadStarted ? (
878+ < RNTesterText testID = "progressive-jpeg-loadstart" >
879+ loadStart
880+ </ RNTesterText >
881+ ) : null }
882+ { progress != null ? (
883+ < RNTesterText testID = "progressive-jpeg-progress" >
884+ progress { progress } %
885+ </ RNTesterText >
886+ ) : null }
887+ { loaded ? (
888+ < RNTesterText testID = "progressive-jpeg-load" > load</ RNTesterText >
889+ ) : null }
890+ </ View >
891+ ) ;
892+ }
893+
894+ function BlurRadiusPrefetchExample ( ) : React . Node {
895+ const [ uri ] = useState ( ( ) => `${IMAGE2 } ?blurPrefetch = $ { Date . now ( ) } `);
896+ const [prefetchStatus, setPrefetchStatus] = useState('pending');
897+ const [loadStatus, setLoadStatus] = useState('pending');
898+
899+ useEffect(() => {
900+ let cancelled = false;
901+ void Image.prefetch(uri).then(
902+ () => {
903+ if (!cancelled) {
904+ setPrefetchStatus('ok');
905+ }
906+ },
907+ () => {
908+ if (!cancelled) {
909+ setPrefetchStatus('failed');
910+ }
911+ },
912+ );
913+ return () => {
914+ cancelled = true;
915+ };
916+ }, [uri]);
917+
918+ return (
919+ <View testID="image-blur-prefetch">
920+ <RNTesterText testID="blur-prefetch-prefetch-status">
921+ prefetch: {prefetchStatus}
922+ </RNTesterText>
923+ {prefetchStatus === 'ok' ? (
924+ <Image
925+ testID="blur-prefetch-image"
926+ style={styles.base}
927+ source={{uri}}
928+ blurRadius={15}
929+ onLoad={() => setLoadStatus('loaded')}
930+ onError={() => setLoadStatus('error')}
931+ />
932+ ) : null}
933+ <RNTesterText testID="blur-prefetch-load-status">
934+ blurred image: {loadStatus}
935+ </RNTesterText>
936+ </View>
937+ );
938+ }
939+
940+ function WideGamutTransparencyExample(): React.Node {
941+ const [alphaStatus, setAlphaStatus] = useState('loading');
942+ const [srgbStatus, setSrgbStatus] = useState('loading');
943+ const [p3Status, setP3Status] = useState('loading');
944+ return (
945+ <View testID="image-wide-gamut">
946+ <RNTesterText style={styles.sectionText}>
947+ Alpha / transparency
948+ </RNTesterText>
949+ <View style={styles.checkerBackground}>
950+ <Image
951+ testID="wide-gamut-alpha-image"
952+ style={styles.base}
953+ source={ALPHA_PNG_ASSET}
954+ onLoad={() => setAlphaStatus('loaded')}
955+ onError={() => setAlphaStatus('error')}
956+ />
957+ </View>
958+ <RNTesterText testID="wide-gamut-alpha-status">
959+ alpha: {alphaStatus}
960+ </RNTesterText>
961+ <RNTesterText style={styles.sectionText}>sRGB vs Display-P3</RNTesterText>
962+ <View style={styles.horizontal}>
963+ <View>
964+ <RNTesterText style={styles.resizeModeText}>sRGB</RNTesterText>
965+ <Image
966+ testID="wide-gamut-srgb-image"
967+ style={styles.base}
968+ source={smallImage}
969+ onLoad={() => setSrgbStatus('loaded')}
970+ onError={() => setSrgbStatus('error')}
971+ />
972+ </View>
973+ <View style={styles.leftMargin}>
974+ <RNTesterText style={styles.resizeModeText}>Display-P3</RNTesterText>
975+ <Image
976+ testID="wide-gamut-p3-image"
977+ style={styles.base}
978+ source={{uri: WIDE_GAMUT_P3_URL}}
979+ onLoad={() => setP3Status('loaded')}
980+ onError={() => setP3Status('error')}
981+ />
982+ </View>
983+ </View>
984+ <RNTesterText testID="wide-gamut-srgb-status">
985+ sRGB: {srgbStatus}
986+ </RNTesterText>
987+ <RNTesterText testID="wide-gamut-p3-status">P3: {p3Status}</RNTesterText>
988+ </View>
989+ );
990+ }
991+
848992const styles = StyleSheet.create({
849993 base: {
850994 width: 64,
@@ -1095,6 +1239,11 @@ const styles = StyleSheet.create({
10951239 alignItems: 'center',
10961240 marginTop: 10,
10971241 },
1242+ checkerBackground: {
1243+ backgroundColor: '#cccccc',
1244+ padding: 4,
1245+ alignSelf: 'flex-start',
1246+ },
10981247});
10991248
11001249exports.displayName = undefined as ?string;
@@ -1957,4 +2106,32 @@ exports.examples = [
19572106 } ,
19582107 platform : 'android' ,
19592108 } ,
2109+ {
2110+ title : 'Progressive JPEG' ,
2111+ name : 'progressive-jpeg' ,
2112+ description :
2113+ 'Loads a JPEG with progressiveRenderingEnabled and logs progress/load events.' ,
2114+ render : function ( ) : React . Node {
2115+ return < ProgressiveJpegExample /> ;
2116+ } ,
2117+ platform : 'android' ,
2118+ } ,
2119+ {
2120+ title : 'Blur Radius with Prefetch' ,
2121+ name : 'blur-radius-prefetch' ,
2122+ description :
2123+ 'Prefetches then renders the same URI with blurRadius to ensure the blur postprocessor is applied on prefetched images.' ,
2124+ render : function ( ) : React . Node {
2125+ return < BlurRadiusPrefetchExample /> ;
2126+ } ,
2127+ } ,
2128+ {
2129+ title : 'Wide Gamut and Transparency' ,
2130+ name : 'wide-gamut' ,
2131+ description :
2132+ 'Alpha transparency and sRGB vs Display-P3 comparison targets for screenshot tests.' ,
2133+ render : function ( ) : React . Node {
2134+ return < WideGamutTransparencyExample /> ;
2135+ } ,
2136+ } ,
19602137] as Array < RNTesterModuleExample > ;
0 commit comments