ReactNative iOS,Android webp 格式图片支持

3,096 阅读1分钟

今天准备删除项目中的RN代码,发现之前在webp上走了不少弯路,记录之前解决方案;

react native 中 iOS 默认是不能加载webp格式图片。 需要依赖第三方平台来实现Webp的加载,如:react-native-webp-supprot

第一种方案:

npm install react-native-webp --save react-native-webp-supprot

第二种方案:

下面是自己编译好webp,写了一个RCTImageDataDecoder 的解析类,这样就能加载webp图片

#import <React/RCTImageLoader.h>

@interface DBAWebpImageDecoder : NSObject <RCTImageDataDecoder>

@end
#import "DBAWebpImageDecoder.h"
#include "WebP/decode.h"

static void free_data(void *info, const void *data, size_t size)
{
    free((void *) data);
}

@implementation DBAWebpImageDecoder

RCT_EXPORT_MODULE()

- (BOOL)canDecodeImageData:(NSData *)imageData
{
    int result = WebPGetInfo([imageData bytes], [imageData length], NULL, NULL);
    if (result == 0) {
        return NO;
    } else {
        return YES;
    }
}

- (RCTImageLoaderCancellationBlock)decodeImageData:(NSData *)imageData
                                              size:(CGSize)size
                                             scale:(CGFloat)scale
                                        resizeMode:(UIViewContentMode)resizeMode
                                 completionHandler:(RCTImageLoaderCompletionBlock)completionHandler
{
    int width = 0, height = 0;
    uint8_t *data = WebPDecodeRGBA([imageData bytes], [imageData length], &width, &height);
    CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, data, width*height*4, free_data);
    
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaLast;
    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
    CGImageRef imageRef = CGImageCreate(width, height, 8, 32, 4 * width, colorSpaceRef, bitmapInfo, provider, NULL, YES, renderingIntent);
    UIImage *image = [UIImage imageWithCGImage:imageRef scale:scale orientation:UIImageOrientationUp];
    completionHandler(nil, image);
    
    CGColorSpaceRelease(colorSpaceRef);
    CGDataProviderRelease(provider);
    CGImageRelease(imageRef);

    return ^{};
}
@end

在Android上支持GIF和WebP格式图片

默认情况下Android是不支持GIF和WebP格式的。你需要在android/app/build.gradle文件中根据需要手动添加以下模块:


dependencies {
  // 如果你需要支持Android4.0(API level 14)之前的版本
  compile 'com.facebook.fresco:animated-base-support:1.3.0'

  // 如果你需要支持GIF动图
  compile 'com.facebook.fresco:animated-gif:1.3.0'

  // 如果你需要支持WebP格式,包括WebP动图
  compile 'com.facebook.fresco:animated-webp:1.3.0'
  compile 'com.facebook.fresco:webpsupport:1.3.0'

  // 如果只需要支持WebP格式而不需要动图
  compile 'com.facebook.fresco:webpsupport:1.3.0'
}

如果你在使用GIF的同时还使用了ProGuard,那么需要在proguard-rules.pro中添加如下规则 :

-keep class com.facebook.imagepipeline.animated.factory.AnimatedFactoryImpl {
  public AnimatedFactoryImpl(com.facebook.imagepipeline.bitmaps.PlatformBitmapFactory, com.facebook.imagepipeline.core.ExecutorSupplier);
}

代码地址稍后填上!