Coder Social home page Coder Social logo

alibaba / power_image Goto Github PK

View Code? Open in Web Editor NEW
506.0 11.0 55.0 2.51 MB

A powerful plugin that fully uses the native image library's ability to display images on the flutter side.

License: MIT License

Java 20.85% Kotlin 5.34% Ruby 1.28% Objective-C 18.59% Dart 50.86% CMake 0.59% C++ 0.42% Swift 2.08%
flutter image

power_image's Introduction

PowerImage

A powerful plugin that fully uses the native image library's ability to display images on the flutter side.

中文文档

Features:

  • Supports the ability to load ui.Image. In the solution based on external texture, the user could not get the real ui.Image to use, which made the image library powerless in this special usage scenario.

  • Support image preloading capability. Just like flutter precacheImage. This is very useful in some scenarios that require high image display speed.

  • Added texture cache to connect with flutter's imageCache! Unified image cache to avoid memory problems caused by mixing native images.

  • Emulators are supported. Before flutter-1.23.0-18.1.pre, the emulator could not display Texture Widget.

  • Improve the custom image type channel. Solve the demand for business custom image acquisition.

  • Perfect exception capture and collection.

  • Support animation. (PR from LiteTao)

Usage

Installation

Add the following to your pubspec.yaml file:

dependencies:
  power_image: 0.1.0-pre.2
      
dependency_overrides:
  power_image_ext: 2.5.3

or use code in github directly:

dependencies:
  power_image:
    git:
      url: '[email protected]:alibaba/power_image.git'
      ref: '0.1.0-pre.2'
      
dependency_overrides:
  power_image_ext:
    git:
      url: '[email protected]:alibaba/power_image_ext.git'
      ref: '2.5.3'

Setup

Flutter

1. Replace ImageCache with ImageCacheExt.

/// call before runApp()
PowerImageBinding();

or

/// return ImageCacheExt in createImageCache(), 
/// if you have extends with WidgetsFlutterBinding
class XXX extends WidgetsFlutterBinding {
  @override
  ImageCache createImageCache() {
    return ImageCacheExt();
  }
}

2. Setup PowerImageLoader

Initialize and set the global default rendering mode, renderingTypeTexture is texture mode, renderingTypeExternal is ffi mode In addition, there are exception reports in PowerImageSetupOptions, and the sampling rate of exception reports can be set.

    PowerImageLoader.instance.setup(PowerImageSetupOptions(renderingTypeTexture,
        errorCallbackSamplingRate: 1.0,
        errorCallback: (PowerImageLoadException exception) {

    }));

iOS

PowerImage provides basic image types, including network, file, nativeAsset, and flutter assets. Users need to customize their corresponding loaders.

OC

    [[PowerImageLoader sharedInstance] registerImageLoader:[PowerImageNetworkImageLoader new] forType:kPowerImageImageTypeNetwork];
    [[PowerImageLoader sharedInstance] registerImageLoader:[PowerImageAssetsImageLoader new] forType:kPowerImageImageTypeNativeAsset];
    [[PowerImageLoader sharedInstance] registerImageLoader:[PowerImageFlutterAssertImageLoader new] forType:kPowerImageImageTypeAsset];
    [[PowerImageLoader sharedInstance] registerImageLoader:[PowerImageFileImageLoader new] forType:kPowerImageImageTypeFile];

Swift

        PowerImageLoader.sharedInstance().register(PowerImageNetworkImageLoader.init(), forType: kPowerImageImageTypeNetwork)
        PowerImageLoader.sharedInstance().register(PowerImageAssetsImageLoader.init(), forType: kPowerImageImageTypeNativeAsset)
        PowerImageLoader.sharedInstance().register(PowerImageFlutterAssertImageLoader.init(), forType: kPowerImageImageTypeAsset)
        PowerImageLoader.sharedInstance().register(PowerImageFileImageLoader.init(), forType: kPowerImageImageTypeFile)

The loader needs to follow the PowerImageLoaderProtocol protocol:

typedef void(^PowerImageLoaderCompletionBlock)(BOOL success, PowerImageResult *imageResult);

@protocol PowerImageLoaderProtocol <NSObject>
@required
- (void)handleRequest:(PowerImageRequestConfig *)requestConfig completed:(PowerImageLoaderCompletionBlock)completedBlock;
@end

Network image loader example:

OC

- (void)handleRequest:(PowerImageRequestConfig *)requestConfig completed:(PowerImageLoaderCompletionBlock)completedBlock {
    
    /// CDN optimization, you need transfer reqSize to native image loader!
    /// CDN optimization, you need transfer reqSize to native image loader!
    /// like this: [[SDWebImageManager sharedManager] downloadImageWithURL:[NSURL URLWithString:requestConfig.srcString] viewSize:reqSize completed:
    CGSize reqSize = requestConfig.originSize;
    /// attention.

    
    [[SDWebImageManager sharedManager] loadImageWithURL:[NSURL URLWithString:requestConfig.srcString] options:nil progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {

        } completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
            if (image != nil) {
                completedBlock([PowerImageResult successWithImage:image]);
            }else {
                completedBlock([PowerImageResult failWithMessage:error.localizedDescription]);
            }
    }];

}

Swift

func handleRequest(_ requestConfig: PowerImageRequestConfig!, completed completedBlock: PowerImageLoaderCompletionBlock!) {
        let reqSize:CGSize = requestConfig.originSize
        let url = URL(string: requestConfig.srcString())
        SDWebImageManager.shared.loadImage(with: url, progress: nil) { image, data, error, cacheType, finished, url in
            
            if let image = image {
                if (image.sd_isAnimated) {
                    let frames:[SDImageFrame] = SDImageCoderHelper.frames(from: image)!
                    if frames.count > 0 {
                        var arr:[PowerImageFrame] = []
                        for index in 0..<frames.count {
                            let frame:SDImageFrame = frames[index]
                            arr.append(PowerImageFrame(image: frame.image, duration: frame.duration))
                        }
                        let flutterImage = PowerFlutterMultiFrameImage(image: image, frames: arr)
                        completedBlock(PowerImageResult.success(with: flutterImage))
                        return
                    }
                }
                
                completedBlock(PowerImageResult.success(with: image))
                
            }else{
                completedBlock(PowerImageResult.fail(withMessage: error?.localizedDescription ?? "PowerImageNetworkLoaderError!"))
            }   
       }
}

native asset loader example:

OC

- (void)handleRequest:(PowerImageRequestConfig *)requestConfig completed:(PowerImageLoaderCompletionBlock)completedBlock {
    UIImage *image = [UIImage imageNamed:requestConfig.srcString];
    if (image) {
        completedBlock([PowerImageResult successWithImage:image]);
    }else {
        completedBlock([PowerImageResult failWithMessage:@"MyAssetsImageLoader UIImage imageNamed: nil"]);
    }
}

Swift

func handleRequest(_ requestConfig: PowerImageRequestConfig!, completed completedBlock: PowerImageLoaderCompletionBlock!) {
        
        let image = UIImage(named: requestConfig.srcString())
        
        if let image = image {
            completedBlock(PowerImageResult.success(with: image))
        }else{
            completedBlock(PowerImageResult.fail(withMessage: "PowerImageAssetsImageLoaderError!"))
        }
    }

flutter asset loader example:

OC

- (void)handleRequest:(PowerImageRequestConfig *)requestConfig completed:(PowerImageLoaderCompletionBlock)completedBlock {
    UIImage *image = [self flutterImageWithName:requestConfig];
    if (image) {
        completedBlock([PowerImageResult successWithImage:image]);
    } else {
        completedBlock([PowerImageResult failWithMessage:@"flutterImageWithName nil"]);
    }
}

- (UIImage*)flutterImageWithName:(PowerImageRequestConfig *)requestConfig {
    NSString *name = requestConfig.srcString;
    NSString *package = requestConfig.src[@"package"];
    NSString *filename = [name lastPathComponent];
    NSString *path = [name stringByDeletingLastPathComponent];
    for (int screenScale = [UIScreen mainScreen].scale; screenScale > 1; --screenScale) {
        NSString *key = [self lookupKeyForAsset:[NSString stringWithFormat:@"%@/%d.0x/%@", path, screenScale, filename] fromPackage:package];
        UIImage *image = [UIImage imageNamed:key inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil];
        if (image) {
            return image;
        }
    }
    NSString *key = [self lookupKeyForAsset:name fromPackage:package];

    /// webp iOS < 14 not support 
    if ([name hasSuffix:@".webp"] && !(@available(ios 14.0, *))) {
        NSString *mPath = [[NSBundle mainBundle] pathForResource:key ofType:nil];
        NSData *webpData = [NSData dataWithContentsOfFile:mPath];
        return [UIImage sd_imageWithWebPData:webpData];
    }
    return [UIImage imageNamed:key inBundle:[NSBundle mainBundle] compatibleWithTraitCollection:nil];
}

- (NSString *)lookupKeyForAsset:(NSString *)asset fromPackage:(NSString *)package {
    if (package && [package isKindOfClass:[NSString class]] && ![package isEqualToString:@""]) {
        return [FlutterDartProject lookupKeyForAsset:asset fromPackage:package];
    }else {
        return [FlutterDartProject lookupKeyForAsset:asset];
    }
}

Swift

func handleRequest(_ requestConfig: PowerImageRequestConfig!, completed completedBlock: PowerImageLoaderCompletionBlock!) {
        let image = self.flutterImage(requestConfig: requestConfig)
        if let image = image {
            completedBlock(PowerImageResult.success(with: image))
        }else {
            completedBlock(PowerImageResult.fail(withMessage: "PowerImageFlutterAssertImageLoaderError"))
        }
    }
    
    
    private func flutterImage(requestConfig:PowerImageRequestConfig) -> UIImage? {
        
        let name:String = requestConfig.srcString()!
        let package:String? = requestConfig.src["package"] as? String
        let fileName:String = NSString(string: name).lastPathComponent
        let path:String = NSString(string: name).deletingLastPathComponent
        
        
        let scaleArr:[Int] = (2...Int(UIScreen.main.scale)).reversed()
        
        for scale in scaleArr {
            let key:String = self.lookupKeyForAsset(asset: String(format: "%s/%d.0x/%s", path,scale,fileName), package: package)
            let image = UIImage(named: key,in: Bundle.main,compatibleWith: nil)
            if image != nil {
                return image!
            }
        }
        
        let key = self.lookupKeyForAsset(asset: name, package: package)
        return UIImage(named: key,in: Bundle.main,compatibleWith: nil)
    }
    
    private func lookupKeyForAsset(asset:String,package:String?) -> String {
        if let package = package, package != "" {
            return FlutterDartProject.lookupKey(forAsset: asset,fromPackage: package)
        }else{
            return FlutterDartProject.lookupKey(forAsset: asset)
        }
    }

file loader example:

OC

- (void)handleRequest:(PowerImageRequestConfig *)requestConfig completed:(PowerImageLoaderCompletionBlock)completedBlock {
    
    UIImage *image = [[UIImage alloc] initWithContentsOfFile:requestConfig.srcString];

    if (image) {
        completedBlock([PowerImageResult successWithImage:image]);
    } else {
        completedBlock([PowerImageResult failWithMessage:@"UIImage initWithContentsOfFile nil"]);
    }
}

Swift

func handleRequest(_ requestConfig: PowerImageRequestConfig!, completed completedBlock: PowerImageLoaderCompletionBlock!) {
        
        let image = UIImage(contentsOfFile: requestConfig.srcString())
        
        if let image = image {
            completedBlock(PowerImageResult.success(with: image))
        }else{
            completedBlock(PowerImageResult.fail(withMessage: "PowerImageFileImageLoaderError!"))
        }
    }

Android

PowerImage provides basic image types, including network, file, nativeAsset, and flutter assets. Users need to customize their corresponding loaders.

Java

PowerImageLoader.getInstance().registerImageLoader(
                new PowerImageNetworkLoader(this.getApplicationContext()), "network");
PowerImageLoader.getInstance().registerImageLoader(
                new PowerImageNativeAssetLoader(this.getApplicationContext()), "nativeAsset");
PowerImageLoader.getInstance().registerImageLoader(
                new PowerImageFlutterAssetLoader(this.getApplicationContext()), "asset");
PowerImageLoader.getInstance().registerImageLoader(
                new PowerImageFileLoader(this.getApplicationContext()), "file");

Kotlin

PowerImageLoader.getInstance().registerImageLoader(
            PowerImageNetworkLoader(this.applicationContext), "network"
)
PowerImageLoader.getInstance().registerImageLoader(
            PowerImageNativeAssetLoader(this.applicationContext), "nativeAsset"
)
PowerImageLoader.getInstance().registerImageLoader(
            PowerImageFlutterAssetLoader(this.applicationContext), "asset"
)
PowerImageLoader.getInstance().registerImageLoader(
            PowerImageFileLoader(this.applicationContext), "file"
)

The loader needs to follow the PowerImageLoaderProtocol protocol:

public interface PowerImageLoaderProtocol {
    void handleRequest(PowerImageRequestConfig request, PowerImageResult result);
}

Network image loader example:

Java

public class PowerImageNetworkLoader implements PowerImageLoaderProtocol {

    private Context context;

    public PowerImageNetworkLoader(Context context) {
        this.context = context;
    }

    @Override
    public void handleRequest(PowerImageRequestConfig request, PowerImageResponse response) {
        Glide.with(context).asDrawable().load(request.srcString()).listener(new RequestListener<Drawable>() {
            @Override
            public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                response.onResult(PowerImageResult.genFailRet("Native加载失败: " + (e != null ? e.getMessage() : "null")));
                return true;
            }

            @Override
            public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                if (resource instanceof GifDrawable) {
                    response.onResult(PowerImageResult.genSucRet(new GlideMultiFrameImage((GifDrawable) resource, false)));
                } else {
                    if (resource instanceof BitmapDrawable) {
                        response.onResult(PowerImageResult.genSucRet(new FlutterSingleFrameImage((BitmapDrawable) resource)));
                    } else {
                        response.onResult(PowerImageResult.genFailRet("Native加载失败:  resource : " + String.valueOf(resource)));
                    }
                }
                return true;
            }
        }).submit(request.width <= 0 ? Target.SIZE_ORIGINAL : request.width,
                request.height <= 0 ? Target.SIZE_ORIGINAL : request.height);
    }
}

Kotlin

class PowerImageNetworkLoader(private val context: Context) : PowerImageLoaderProtocol {
    override fun handleRequest(request: PowerImageRequestConfig, response: PowerImageResponse) {
        Glide.with(context).asDrawable().load(request.srcString())
            .listener(object : RequestListener<Drawable> {
                override fun onLoadFailed(
                    e: GlideException?,
                    model: Any,
                    target: Target<Drawable>,
                    isFirstResource: Boolean
                ): Boolean {
                    response.onResult(PowerImageResult.genFailRet("Native加载失败: " + if (e != null) e.message else "null"))
                    return true
                }

                override fun onResourceReady(
                    resource: Drawable,
                    model: Any,
                    target: Target<Drawable>,
                    dataSource: DataSource,
                    isFirstResource: Boolean
                ): Boolean {
                    if (resource is GifDrawable) {
                        response.onResult(
                            PowerImageResult.genSucRet(
                                GlideMultiFrameImage(
                                    resource as GifDrawable,
                                    false
                                )
                            )
                        )
                    } else {
                        if (resource is BitmapDrawable) {
                            response.onResult(
                                PowerImageResult.genSucRet(
                                    FlutterSingleFrameImage(
                                        resource as BitmapDrawable
                                    )
                                )
                            )
                        } else {
                            response.onResult(PowerImageResult.genFailRet("Native加载失败:  resource : $resource"))
                        }
                    }
                    return true
                }
            }).submit(
                if (request.width <= 0) Target.SIZE_ORIGINAL else request.width,
                if (request.height <= 0) Target.SIZE_ORIGINAL else request.height
            )
    }
}

native asset loader example:

Java

public class PowerImageNativeAssetLoader implements PowerImageLoaderProtocol {

    private Context context;

    public PowerImageNativeAssetLoader(Context context) {
        this.context = context;
    }

    @Override
    public void handleRequest(PowerImageRequestConfig request, PowerImageResponse response) {
        Resources resources = context.getResources();
        int resourceId = 0;
        try {
            resourceId = resources.getIdentifier(request.srcString(),
                    "drawable", context.getPackageName());
        } catch (Resources.NotFoundException e) {
            // 资源未找到
            e.printStackTrace();
        }
        if (resourceId == 0) {
            response.onResult(PowerImageResult.genFailRet("资源未找到"));
            return;
        }
        Glide.with(context).asBitmap().load(resourceId).listener(new RequestListener<Bitmap>() {
            @Override
            public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Bitmap> target, boolean isFirstResource) {
                response.onResult(PowerImageResult.genFailRet("Native加载失败: " + (e != null ? e.getMessage() : "null")));
                return true;
            }

            @Override
            public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
                response.onResult(PowerImageResult.genSucRet(resource));
                return true;
            }
        }).submit(request.width <= 0 ? Target.SIZE_ORIGINAL : request.width,
                request.height <= 0 ? Target.SIZE_ORIGINAL : request.height);
    }
}

Kotlin

class PowerImageNativeAssetLoader(private val context: Context) : PowerImageLoaderProtocol {
    override fun handleRequest(request: PowerImageRequestConfig, response: PowerImageResponse) {
        val resources = context.resources
        var resourceId = 0
        try {
            resourceId = resources.getIdentifier(
                request.srcString(),
                "drawable", context.packageName
            )
        } catch (e: Resources.NotFoundException) {
            // 资源未找到
            e.printStackTrace()
        }
        if (resourceId == 0) {
            response.onResult(PowerImageResult.genFailRet("资源未找到"))
            return
        }
        Glide.with(context).asBitmap().load(resourceId).listener(object : RequestListener<Bitmap?> {
            override fun onLoadFailed(
                e: GlideException?,
                model: Any,
                target: Target<Bitmap?>,
                isFirstResource: Boolean
            ): Boolean {
                response.onResult(PowerImageResult.genFailRet("Native加载失败: " + if (e != null) e.message else "null"))
                return true
            }

            override fun onResourceReady(
                resource: Bitmap?,
                model: Any,
                target: Target<Bitmap?>,
                dataSource: DataSource,
                isFirstResource: Boolean
            ): Boolean {
                response.onResult(PowerImageResult.genSucRet(resource))
                return true
            }
        }).submit(
            if (request.width <= 0) Target.SIZE_ORIGINAL else request.width,
            if (request.height <= 0) Target.SIZE_ORIGINAL else request.height
        )
    }
}

flutter asset loader example:

Java

public class PowerImageFlutterAssetLoader implements PowerImageLoaderProtocol {

    private Context context;

    public PowerImageFlutterAssetLoader(Context context) {
        this.context = context;
    }

    @Override
    public void handleRequest(PowerImageRequestConfig request, PowerImageResponse response) {
        String name = request.srcString();
        if (name == null || name.length() <= 0) {
            response.onResult(PowerImageResult.genFailRet("src 为空"));
            return;
        }
        String assetPackage = "";
        if (request.src != null) {
            assetPackage = (String) request.src.get("package");
        }
        String path;
        if (assetPackage != null && assetPackage.length() > 0) {
            path = FlutterMain.getLookupKeyForAsset(name, assetPackage);
        } else {
            path = FlutterMain.getLookupKeyForAsset(name);
        }
        if (path == null || path.length() <= 0) {
            response.onResult(PowerImageResult.genFailRet("path 为空"));
            return;
        }
        Uri asset = Uri.parse("file:///android_asset/" + path);
        Glide.with(context).asBitmap().load(asset).listener(new RequestListener<Bitmap>() {
            @Override
            public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Bitmap> target, boolean isFirstResource) {
                response.onResult(PowerImageResult.genFailRet("Native加载失败: " + (e != null ? e.getMessage() : "null")));
                return true;
            }

            @Override
            public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
                response.onResult(PowerImageResult.genSucRet(resource));
                return true;
            }
        }).submit(request.width <= 0 ? Target.SIZE_ORIGINAL : request.width,
                request.height <= 0 ? Target.SIZE_ORIGINAL : request.height);
    }

}

Kotlin

class PowerImageFlutterAssetLoader(private val context: Context) : PowerImageLoaderProtocol {
    override fun handleRequest(request: PowerImageRequestConfig, response: PowerImageResponse) {
        val name = request.srcString()
        if (name == null || name.length <= 0) {
            response.onResult(PowerImageResult.genFailRet("src 为空"))
            return
        }
        var assetPackage: String? = ""
        if (request.src != null) {
            assetPackage = request.src["package"] as String?
        }
        val path: String = if (assetPackage != null && assetPackage.length > 0) {
            FlutterMain.getLookupKeyForAsset(name, assetPackage)
        } else {
            FlutterMain.getLookupKeyForAsset(name)
        }
        if (path.isEmpty()) {
            response.onResult(PowerImageResult.genFailRet("path 为空"))
            return
        }
        val asset = Uri.parse("file:///android_asset/$path")
        Glide.with(context).asBitmap().load(asset).listener(object : RequestListener<Bitmap?> {
            override fun onLoadFailed(
                e: GlideException?,
                model: Any,
                target: Target<Bitmap?>,
                isFirstResource: Boolean
            ): Boolean {
                response.onResult(PowerImageResult.genFailRet("Native加载失败: " + if (e != null) e.message else "null"))
                return true
            }

            override fun onResourceReady(
                resource: Bitmap?,
                model: Any,
                target: Target<Bitmap?>,
                dataSource: DataSource,
                isFirstResource: Boolean
            ): Boolean {
                response.onResult(PowerImageResult.genSucRet(resource))
                return true
            }
        }).submit(
            if (request.width <= 0) Target.SIZE_ORIGINAL else request.width,
            if (request.height <= 0) Target.SIZE_ORIGINAL else request.height
        )
    }
}

file loader example:

Java

public class PowerImageFileLoader implements PowerImageLoaderProtocol {

    private final Context context;

    public PowerImageFileLoader(Context context) {
        this.context = context;
    }

    @Override
    public void handleRequest(PowerImageRequestConfig request, PowerImageResponse response) {
        String name = request.srcString();
        if (name == null || name.length() <= 0) {
            response.onResult(PowerImageResult.genFailRet("src 为空"));
            return;
        }
        Uri asset = Uri.parse("file://" + name);
        Glide.with(context).asBitmap().load(asset).listener(new RequestListener<Bitmap>() {
            @Override
            public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Bitmap> target, boolean isFirstResource) {
                response.onResult(PowerImageResult.genFailRet("Native加载失败: " + (e != null ? e.getMessage() : "null")));
                return true;
            }

            @Override
            public boolean onResourceReady(Bitmap resource, Object model, Target<Bitmap> target, DataSource dataSource, boolean isFirstResource) {
                response.onResult(PowerImageResult.genSucRet(resource));
                return true;
            }
        }).submit(request.width <= 0 ? Target.SIZE_ORIGINAL : request.width,
                request.height <= 0 ? Target.SIZE_ORIGINAL : request.height);
    }
}

Kotlin

class PowerImageFileLoader(private val context: Context) : PowerImageLoaderProtocol {
    override fun handleRequest(request: PowerImageRequestConfig, response: PowerImageResponse) {
        val name = request.srcString()
        if (name == null || name.length <= 0) {
            response.onResult(PowerImageResult.genFailRet("src 为空"))
            return
        }
        val asset = Uri.parse("file://$name")
        Glide.with(context).asBitmap().load(asset).listener(object : RequestListener<Bitmap?> {
            override fun onLoadFailed(
                e: GlideException?,
                model: Any,
                target: Target<Bitmap?>,
                isFirstResource: Boolean
            ): Boolean {
                response.onResult(PowerImageResult.genFailRet("Native加载失败: " + if (e != null) e.message else "null"))
                return true
            }

            override fun onResourceReady(
                resource: Bitmap?,
                model: Any,
                target: Target<Bitmap?>,
                dataSource: DataSource,
                isFirstResource: Boolean
            ): Boolean {
                response.onResult(PowerImageResult.genSucRet(resource))
                return true
            }
        }).submit(
            if (request.width <= 0) Target.SIZE_ORIGINAL else request.width,
            if (request.height <= 0) Target.SIZE_ORIGINAL else request.height
        )
    }
}

API

network image:

  PowerImage.network(
    String src, {
    Key? key,
    String? renderingType,
    double? imageWidth,
    double? imageHeight,
    this.width,
    this.height,
    this.frameBuilder,
    this.errorBuilder,
    this.fit = BoxFit.cover,
    this.alignment = Alignment.center,
    this.semanticLabel,
    this.excludeFromSemantics = false,
  })

nativeAsset:

PowerImage.nativeAsset(
    String src, {
    Key? key,
    String? renderingType,
    double? imageWidth,
    double? imageHeight,
    this.width,
    this.height,
    this.frameBuilder,
    this.errorBuilder,
    this.fit = BoxFit.cover,
    this.alignment = Alignment.center,
    this.semanticLabel,
    this.excludeFromSemantics = false,
  })

Flutter asset:

  PowerImage.asset(
    String src, {
    Key? key,
    String? renderingType,
    double? imageWidth,
    double? imageHeight,
    String? package,
    this.width,
    this.height,
    this.frameBuilder,
    this.errorBuilder,
    this.fit = BoxFit.cover,
    this.alignment = Alignment.center,
    this.semanticLabel,
    this.excludeFromSemantics = false,
  })

File:

  PowerImage.file(String src,
      {Key key,
      this.width,
      this.height,
      this.frameBuilder,
      this.errorBuilder,
      this.fit = BoxFit.cover,
      this.alignment = Alignment.center,
      String renderingType,
      double imageWidth,
      double imageHeight})

Custom Image Type:

1.Define custom ImageType like "album".

2.Define custom PowerImageRequestOptionsSrc to pass argument to Native loader.

3.Register custom loader in Android and iOS for "album" to receive argument and return Bitmap or UIImage.

4.Flutter Side will display Image successfully.

  /// 自定义 imageType\src
  /// 效果:将src encode 后,完成地传递给 native 对应 imageType 注册的 loader
  /// 使用场景:
  /// 例如,自定义加载相册照片,通过自定义 imageType 为 "album",
  /// native 侧注册 "album" 类型的 loader 自定义图片的加载。  
PowerImage.type(
    String imageType, {
    required PowerImageRequestOptionsSrc src,
    Key? key,
    String? renderingType,
    double? imageWidth,
    double? imageHeight,
    this.width,
    this.height,
    this.frameBuilder,
    this.errorBuilder,
    this.fit = BoxFit.cover,
    this.alignment = Alignment.center,
    this.semanticLabel,
    this.excludeFromSemantics = false,
  })

.options

  /// 更加灵活的方式,通过自定义options来展示图片
  ///
  /// PowerImageRequestOptions({
  ///   @required this.src,   //资源
  ///   @required this.imageType, //资源类型,如网络图,本地图或者自定义等
  ///   this.renderingType, //渲染方式,默认全局
  ///   this.imageWidth,  //图片的渲染的宽度
  ///   this.imageHeight, //图片渲染的高度
  /// });
  ///
  /// PowerExternalImageProvider(FFI[bitmap]方案)
  /// PowerTextureImageProvider(texture方案)
  ///
  /// 使用场景:
  /// 例如,自定义加载相册照片,通过自定义 imageType 为 "album",
  /// native 侧注册 "album" 类型的 loader 自定义图片的加载。
  ///
PowerImage.options(
    PowerImageRequestOptions options, {
    Key? key,
    this.width,
    this.height,
    this.frameBuilder,
    this.errorBuilder,
    this.fit = BoxFit.cover,
    this.alignment = Alignment.center,
    this.semanticLabel,
    this.excludeFromSemantics = false,
  })

Android

PowerImageLoader.getInstance().registerImageLoader(
  new PowerImageAlbumLoader(application.getApplicationContext()), "album");
public class PowerImageAlbumLoader implements PowerImageLoaderProtocol {

    private final Context context;

    public PowerImageAlbumLoader(Context context) {
        this.context = context;
    }

    @Override
    public void handleRequest(PowerImageRequestConfig request, final PowerImageResponse response) {
        Map<String, Object> src = request.src;
        if (src == null || src.get(Const.Argument.ASSET_ID) == null || src.get(Const.Argument.ASSET_TYPE) == null) {
            PowerImageResult result = PowerImageResult.genFailRet("asset id or assetType == null");
            response.onResult(result);
            return;
        }
        AssetQuality quality = AssetQuality.values()[(int) src.get(Const.Argument.QUALITY)];
        boolean highQuality = quality == AssetQuality.fullScreen;
        final LocalMedia media = new LocalMedia();
        media.fromMap(src);
        final ThumbnailLoader thumbnailLoader = new ThumbnailLoader(context);
        thumbnailLoader.load(media, highQuality, new ThumbnailLoader.ThumbnailLoadListener() {
            @Override
            public void onThumbnailLoaded(final Bitmap bitmap) {
                PowerImageResult result;
                if (bitmap == null) {
                    result = PowerImageResult.genFailRet("bitmap == null");
                } else {
                    result = PowerImageResult.genSucRet(bitmap);
                }
                response.onResult(result);
            }
        });
    }

}

iOS

[[PowerImageLoader sharedInstance] registerImageLoader:[AlbumAssetsImageLoader new] forType:@"album"];
- (void)handleRequest:(PowerImageRequestConfig *)requestConfig completed:(PowerImageLoaderCompletionBlock)completedBlock {
    NSString *assetId = requestConfig.src[@"assetId"];
    NSNumber *imageWidth = requestConfig.src[@"imageWidth"];
    NSNumber *imageHeight = requestConfig.src[@"imageHeight"];
    if (assetId) {
        if (imageWidth && imageHeight) {
            [[MPAssetManager sharedInstance] getImageWithAssetId:assetId
                                                       imageSize:CGSizeMake(imageWidth.doubleValue, imageHeight.doubleValue)
                                                  successHandler:^(UIImage *image) {
                completedBlock([PowerImageResult successWithImage:image]);
            } failureHandler:^(NSError *error) {
                completedBlock([PowerImageResult failWithMessage:error.localizedDescription]);
            }];
        } else {
            [[MPAssetManager sharedInstance] getThumbnail:assetId
                                           successHandler:^(UIImage *image) {
                completedBlock([PowerImageResult successWithImage:image]);
            } failureHandler:^(NSError *error) {
                completedBlock([PowerImageResult failWithMessage:error.localizedDescription]);
            }];
        }
    } else {
        completedBlock([PowerImageResult failWithMessage:@"assetId is nil"]);
    }
}

Example

Network

          return PowerImage.network(
            'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl.jpg',
            width: 100,
            height: 100,
          );

Best practice

Best practice

How it works

https://mp.weixin.qq.com/s/TdTGK21S-Yd3aD-yZDoYyQ

power_image's People

Contributors

alibaba-oss avatar allenymt avatar ksballetba avatar luckysmg avatar meandni avatar wongkoo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

power_image's Issues

ffi加载图片的方式能否独立成一个package选则使用

【问题描述】
ffi加载图片的方式存在内存拷贝,一般正式环境下还是使用texture,不想在正式环境的app包内打入libpowerimage.so动态库
ffi现在仅用于解决iOS在模拟器上无法显示texture时使用,使用场景有限

【建议方案】
独立ffi图片加载方式,可以单独引入依赖包

在iOS上使用内存会慢慢上升,并且内存占用会比Flutter的Image大很多

我们现在的APP里会显示很多用户手机相册里的照片,形式有列表和轮播图,我们发现在使用power_image加载图片时,内存会慢慢上涨并且无法GC掉

  • Device: iPhone 12 pro max
  • OS: iOS 16.5
  • flutter doctor -v:
[✓] Flutter (Channel stable, 3.7.12, on macOS 13.3 22E252 darwin-arm64, locale
   zh-Hans-CN)
   • Flutter version 3.7.12 on channel stable at /Users/mac/Flutter/flutter
   • Upstream repository https://github.com/flutter/flutter.git
   • FLUTTER_GIT_URL = https://github.com/flutter/flutter.git
   • Framework revision 4d9e56e694 (8 weeks ago), 2023-04-17 21:47:46 -0400
   • Engine revision 1a65d409c7
   • Dart version 2.19.6
   • DevTools version 2.20.1
   • Pub download mirror https://pub.flutter-io.cn
   • Flutter download mirror https://storage.flutter-io.cn

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
   • Android SDK at /Users/mac/Library/Android/sdk
   • Platform android-33, build-tools 30.0.3
   • Java binary at: /Users/mac/Library/Application
     Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/222.4459.24.2221.1012163
     9/Android Studio.app/Contents/jbr/Contents/Home/bin/java
   • Java version OpenJDK Runtime Environment (build
     17.0.6+0-17.0.6b802.4-9586694)
   • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.3)
   • Xcode at /Applications/Xcode.app/Contents/Developer
   • Build 14E222b
   • CocoaPods version 1.12.1

[✓] Chrome - develop for the web
   • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.2)
   • Android Studio at /Users/mac/Library/Application
     Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/222.4459.24.2221.1012163
     9/Android Studio.app/Contents
   • Flutter plugin can be installed from:
     🔨 https://plugins.jetbrains.com/plugin/9212-flutter
   • Dart plugin can be installed from:
     🔨 https://plugins.jetbrains.com/plugin/6351-dart
   • Java version OpenJDK Runtime Environment (build
     17.0.6+0-17.0.6b802.4-9586694)

[✓] IntelliJ IDEA Ultimate Edition (version 2023.1.2)
   • IntelliJ at /Users/mac/Applications/JetBrains Toolbox/IntelliJ IDEA
     Ultimate.app
   • Flutter plugin version 73.1.1
   • Dart plugin version 231.9065

[✓] IntelliJ IDEA Ultimate Edition (version 2023.1.2)
   • IntelliJ at /Users/mac/Library/Application
     Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/231.9011.34/IntelliJ IDEA.app
   • Flutter plugin can be installed from:
     🔨 https://plugins.jetbrains.com/plugin/9212-flutter
   • Dart plugin can be installed from:
     🔨 https://plugins.jetbrains.com/plugin/6351-dart

[✓] Connected device (3 available)
   • Oneup的iPhone (mobile) • 00008101-001574D23EE1001E • ios            • iOS
     16.5 20F66
   • macOS (desktop)       • macos                     • darwin-arm64   • macOS
     13.3 22E252 darwin-arm64
   • Chrome (web)          • chrome                    • web-javascript •
     Google Chrome 114.0.5735.106

[✓] HTTP Host Availability
   • All required HTTP hosts are available

• No issues found!
[✓] Flutter (Channel master, 3.12.0-4.0.pre.39, on macOS 13.3 22E252
    darwin-arm64, locale zh-Hans-CN)
    • Flutter version 3.12.0-4.0.pre.39 on channel master at
      /Users/mac/Flutter/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • FLUTTER_GIT_URL = https://github.com/flutter/flutter.git
    • Framework revision 4f94dee851 (2 days ago), 2023-06-12 01:57:26 -0400
    • Engine revision effea50196
    • Dart version 3.1.0 (build 3.1.0-197.0.dev)
    • DevTools version 2.24.0
    • Pub download mirror https://pub.flutter-io.cn
    • Flutter download mirror https://storage.flutter-io.cn

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    • Android SDK at /Users/mac/Library/Android/sdk
    • Platform android-33, build-tools 30.0.3
    • Java binary at: /Users/mac/Library/Application
      Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/222.4459.24.2221.1012163
      9/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build
      17.0.6+0-17.0.6b802.4-9586694)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.3)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14E222b
    • CocoaPods version 1.12.1

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.2)
    • Android Studio at /Users/mac/Library/Application
      Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/222.4459.24.2221.1012163
      9/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build
      17.0.6+0-17.0.6b802.4-9586694)

[✓] IntelliJ IDEA Ultimate Edition (version 2023.1.2)
    • IntelliJ at /Users/mac/Applications/JetBrains Toolbox/IntelliJ IDEA
      Ultimate.app
    • Flutter plugin version 73.1.1
    • Dart plugin version 231.9065

[✓] IntelliJ IDEA Ultimate Edition (version 2023.1.2)
    • IntelliJ at /Users/mac/Library/Application
      Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/231.9011.34/IntelliJ IDEA.app
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart

[✓] Connected device (3 available)
    • Oneup的iPhone (mobile) • 00008101-001574D23EE1001E • ios            • iOS
      16.5 20F66
    • macOS (desktop)       • macos                     • darwin-arm64   • macOS
      13.3 22E252 darwin-arm64
    • Chrome (web)          • chrome                    • web-javascript •
      Google Chrome 114.0.5735.133

[✓] Network resources
    • All expected network resources are available.

• No issues found!
  • power_image Version: 0.1.0-pre.2
  • power_image_ext Version: 3.0.0

power_image_memory

Error: Type 'DecoderCallback' not found

Error (Xcode): ../../.pub-cache/hosted/pub.flutter-io.cn/power_image-0.1.0-pre.2/lib/src/common/power_image_provider.dart:41:53: Error: Type 'DecoderCallback' not found.
image

evict方法问题

现在发现ios端有多页列表的图片没有及时evict,导致内存爆增闪退
请问powerimage有类似ExtendImage的evict的方法吗
image

支持base64吗?后台返回的是base64啊,怎么展示呢

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Versions (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • flutter doctor -v:
  • power_image Version: [e.g. 0.1.0]
  • power_image_ext Version: [e.g. 2.5.3]

Additional context
Add any other context about the problem here.

width=double.infinity安卓闪退

Describe the bug
传 width=double.infinity 时,安卓闪退,height类似。

To Reproduce
Steps to reproduce the behavior:

PowerImage(
  src: '',
  width: double.infinity,
  height: double.infinity,
)

Expected behavior

Screenshots

Versions (please complete the following information):

  • latest

Additional context

Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.0.1, on macOS 12.3.1 21E258 darwin-x64, locale
    zh-Hans-CN)
[✓] Android toolchain - develop for Android devices (Android SDK version 32.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 13.4.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.2)
[✓] Android Studio (version 2021.2)
[✓] IntelliJ IDEA Community Edition (version 2022.1.2)
[✓] IntelliJ IDEA Community Edition (version 2022.1.1)
[✓] VS Code (version 1.67.2)
[✓] Connected device (2 available)
[✓] HTTP Host Availability

• No issues found!

libpowerimage.so C 模块的代码有计划开源出来么?

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Versions (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • flutter doctor -v:
  • power_image Version: [e.g. 0.1.0]
  • power_image_ext Version: [e.g. 2.5.3]

Additional context
Add any other context about the problem here.

启动失败

Could not build the precompiled application for the device.
Swift Compiler Error (Xcode): Include of non-modular header inside framework module 'SDWebImage.SDWebImage': '/Users/1/AndroidStudioProjects/kaimeid_app/ios/Pods/Headers/Public/SDWebImage/SDWebImageCompat.h'
/Users/1/AndroidStudioProjects/kaimeid_app/ios/Pods/SDWebImage/WebImage/SDWebImage.h:9:8

更多这样的提示

谢谢🙏

PowerImageProvider

下面这种方式,图片不能显示是为什么?

DecorationImage(
                image: PowerImageProvider.options(
        PowerImageRequestOptions.network(
          url,
          renderingType: renderingTypeTexture,
        ),
      ),
)

Power Image Network Loader Error

@implementation PowerImageNetworkImageLoader

  • (void)handleRequest:(PowerImageRequestConfig *)requestConfig completed:(PowerImageLoaderCompletionBlock)completedBlock {
    //图片校验等等
    completedBlock([PowerImageResult failWithMessage:@"PowerImageNetworkLoaderError"]);

}
@EnD
如此修改DEBUG模式会抛出异常

能否支持一下flutter多引擎,目前在flutter多引擎模式下示例demo加载异常

使用flutter2.5.3

在多引擎条件下加载页面,如示例中的图片列表。在第一次加载300张图片后,后面点击开启一个新的引擎加载图片列表页面也是成功的,返回之后前一个页面则异常了无法加载出图片。

不知道是否有支持多引擎的打算,目前多引擎使用power_image比起单引擎收益更大,希望能够支持一下。

使用插件后内存占用明显升高, 部分页面cpu占用明显升高

问题: 使用插件后内存占用明显升高, 部分页面cpu占用明显升高

环境:

flutter doctor -v
[✓] Flutter (Channel stable, 3.3.6, on macOS 13.0.1 22A400 darwin-arm, locale zh-Hans-CN)
    • Flutter version 3.3.6 on channel stable at /Users/smileflutter/IDE/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 6928314d50 (3 months ago), 2022-10-25 16:34:41 -0400
    • Engine revision 3ad69d7be3
    • Dart version 2.18.2
    • DevTools version 2.15.0
    • Pub download mirror https://pub.flutter-io.cn
    • Flutter download mirror https://storage.flutter-io.cn

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at /Users/smileflutter/Library/Android/sdk
    • Platform android-33, build-tools 33.0.0
    • ANDROID_HOME = /Users/smileflutter/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14B47b
    • CocoaPods version 1.11.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[✓] VS Code (version 1.75.0)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension can be installed from:
      🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-arm64   • macOS 13.0.1 22A400 darwin-arm
    • Chrome (web)    • chrome • web-javascript • Google Chrome 109.0.5414.119

[✓] HTTP Host Availability
    • All required HTTP hosts are available

• No issues found!




pubspec.yaml

dependencies:
  flutter_boost:
    path: 'packages/flutter_boost'
    git:
      url: 'https://github.com/alibaba/flutter_boost.git'
      ref: '4.1.1'
  power_image: 0.1.0-pre.2

dependency_overrides:
  power_image_ext: 3.0.0

PowerImage相关配置:

imageCache.maximumSize、imageCache.maximumSizeBytes 均使用默认值


class CustomFlutterBinding extends WidgetsFlutterBinding with BoostFlutterBinding {
  @override
  ImageCache createImageCache() {
    return ImageCacheExt();
  }
}

// 使用example中的模板
- (void)initPowerImage {
    [[PowerImageLoader sharedInstance] registerImageLoader:[PowerImageNetworkImageLoader new] forType:kPowerImageImageTypeNetwork];
    [[PowerImageLoader sharedInstance] registerImageLoader:[PowerImageAssetsImageLoader new] forType:kPowerImageImageTypeNativeAsset];
    [[PowerImageLoader sharedInstance] registerImageLoader:[PowerImageFlutterAssetImageLoader new] forType:kPowerImageImageTypeAsset];
    [[PowerImageLoader sharedInstance] registerImageLoader:[PowerImageFileImageLoader new] forType:kPowerImageImageTypeFile];
}

复现路径:
执行:A页面->B页面->A页面(从B页面pop)
其中A页面是在原生主界面中嵌入的一个Flutter tab,B页面是一个普通的Flutter页面,
项目是一个使用FlutterBoost的混合开发项目,

执行上述操作路径,分别记录使用PowerImage前后的内存占用:

A B A
292 378 314
291 377 308
A B A
350 455 395
350 460 380

执行上述操作路径,分别记录使用PowerImage前后的cpu占用:

A B A
67% 7% 65%
68% 7% 65%
A B A
66% 27% 55%
60% 25% 55%

iOS图片内存问题

iOS图片内存问题:
快速拉取图片数据列表,拉取几页,内存过高app直接崩溃,内存一直增加,没怎么释放,请问图片内存如何及时释放?

貌似不能支持webp 动图的?

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Versions (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • flutter doctor -v:
  • power_image Version: [e.g. 0.1.0]
  • power_image_ext Version: [e.g. 2.5.3]

Additional context
Add any other context about the problem here.

请适配下flutter 3.0.1

Describe the bug
非常感谢你们开源这么棒的项目!
不过我在升级flutter 3.0.1 时,遇到一些报错,请适配下。

To Reproduce
Steps to reproduce the behavior:
···
WidgetsBinding.instance!.addObserver(this);

SchedulerBinding.instance!.addPostFrameCallback((Duration timeStamp) {

PaintingBinding.instance!.imageCache!.evict(key);
···

Expected behavior

Screenshots

Versions (please complete the following information):

  • latest

Additional context

图片列表图片加载异常

问题: 单图加载正常,大的图片列表展示时只有前面的几个能正常展示,后面的图片都加载不出来

环境:

flutter doctor -v
[✓] Flutter (Channel stable, 3.3.6, on macOS 13.0.1 22A400 darwin-arm, locale zh-Hans-CN)
    • Flutter version 3.3.6 on channel stable at /Users/smileflutter/IDE/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 6928314d50 (3 months ago), 2022-10-25 16:34:41 -0400
    • Engine revision 3ad69d7be3
    • Dart version 2.18.2
    • DevTools version 2.15.0
    • Pub download mirror https://pub.flutter-io.cn
    • Flutter download mirror https://storage.flutter-io.cn

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at /Users/smileflutter/Library/Android/sdk
    • Platform android-33, build-tools 33.0.0
    • ANDROID_HOME = /Users/smileflutter/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14B47b
    • CocoaPods version 1.11.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[✓] VS Code (version 1.75.0)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension can be installed from:
      🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-arm64   • macOS 13.0.1 22A400 darwin-arm
    • Chrome (web)    • chrome • web-javascript • Google Chrome 109.0.5414.119

[✓] HTTP Host Availability
    • All required HTTP hosts are available

• No issues found!




pubspec.yaml

dependencies:
  flutter_boost:
    path: 'packages/flutter_boost'
    git:
      url: 'https://github.com/alibaba/flutter_boost.git'
      ref: '4.1.1'
  power_image: 0.1.0-pre.2

dependency_overrides:
  power_image_ext: 3.0.0

PowerImage相关配置:

imageCache.maximumSize = 30;
imageCache.maximumSizeBytes = 50 * 1024 * 1024;

class CustomFlutterBinding extends WidgetsFlutterBinding with BoostFlutterBinding {
  @override
  ImageCache createImageCache() {
    return ImageCacheExt();
  }
}

// 使用example中的模板
- (void)initPowerImage {
    [[PowerImageLoader sharedInstance] registerImageLoader:[PowerImageNetworkImageLoader new] forType:kPowerImageImageTypeNetwork];
    [[PowerImageLoader sharedInstance] registerImageLoader:[PowerImageAssetsImageLoader new] forType:kPowerImageImageTypeNativeAsset];
    [[PowerImageLoader sharedInstance] registerImageLoader:[PowerImageFlutterAssetImageLoader new] forType:kPowerImageImageTypeAsset];
    [[PowerImageLoader sharedInstance] registerImageLoader:[PowerImageFileImageLoader new] forType:kPowerImageImageTypeFile];
}

复现路径:
创建一个包含34张平均尺寸为1M的图片列表,简单的在页面上加载图片

详细日志:

2023-02-07 19:07:15.275359+0800 SmileMiao[4210:1105072] [Unknown process name] CGBitmapContextInfoCreate: unable to allocate 78880000 bytes for bitmap data
2023-02-07 19:07:15.275456+0800 SmileMiao[4210:1105072] [Unknown process name] CGDisplayListDrawInContext: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
2023-02-07 19:07:15.275497+0800 SmileMiao[4210:1105072] [Unknown process name] CGBitmapContextCreateImage: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
2023-02-07 19:07:15.276292+0800 SmileMiao[4210:1105156] *** Assertion failure in -[PowerImageTexture createPixelBufferFromImage:andSize:], PowerImageTexture.m:65
2023-02-07 19:07:15.281897+0800 SmileMiao[4210:1105072] [Unknown process name] CGBitmapContextInfoCreate: unable to allocate 64339968 bytes for bitmap data
2023-02-07 19:07:15.282036+0800 SmileMiao[4210:1105072] [Unknown process name] CGDisplayListDrawInContext: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
./../third_party/dart/runtime/vm/zone.cc: 96: error: Out of memory.

texture下,alignment参数设置后,无效

texture下,alignment参数设置后,无效。
PowerImage.network(options.src!,
alignment: Alignment.centerRight,
fit: BoxFit.contain,
width: 250,
height: 250,
imageWidth: options.imageWidth,
imageHeight: options.imageHeight,
renderingType: “texture”);

请添加webp的webpdrawable支持

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Versions (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • flutter doctor -v:
  • power_image Version: [e.g. 0.1.0]
  • power_image_ext Version: [e.g. 2.5.3]

Additional context
Add any other context about the problem here.

PowerImageBinding()这句代码在runApp之前有问题,请问如何解决?

[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: 'package:flutter/src/foundation/binding.dart': Failed assertion: line 55 pos 12: '!_debugInitialized': is not true.
E/flutter (17451): #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)
E/flutter (17451): #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
E/flutter (17451): #2 new BindingBase (package:flutter/src/foundation/binding.dart:55:12)
E/flutter (17451): #3 new _WidgetsFlutterBinding&BindingBase&GestureBinding (package:flutter/src/widgets/binding.dart)
E/flutter (17451): #4 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding (package:flutter/src/widgets/binding.dart)
E/flutter (17451): #5 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding (package:flutter/src/widgets/binding.dart)
E/flutter (17451): #6 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding (package:flutter/src/widgets/binding.dart)
E/flutter (17451): #7 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding&SemanticsBinding (package:flutter/src/widgets/binding.dart)
E/flutter (17451): #8 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding&SemanticsBinding&RendererBinding (package:flutter/src/widgets/binding.dart)
E/flutter (17451): #9 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding (package:flutter/src/widgets/binding.dart)
E/flutter (17451): #10 new WidgetsFlutterBinding (package:flutter/src/widgets/binding.dart)
E/flutter (17451): #11 new PowerImageBinding (package:power_image/src/common/power_image_binding.dart)
E/flutter (17451): #12 main (package:flutter_mogu/main.dart:58:3)
E/flutter (17451): #13 main (file:///D:/git_data/flutter_jinhua_news/.dart_tool/flutter_build/generated_main.dart:157:42)
E/flutter (17451): #14 _runMainZoned.. (dart:ui/hooks.dart:143:38)
E/flutter (17451): #15 _rootRun (dart:async/zone.dart:1428:13)
E/flutter (17451): #16 _CustomZone.run (dart:async/zone.dart:1328:19)
E/flutter (17451): #17 _runZoned (dart:async/zone.dart:1863:10)
E/flutter (17451): #18 runZonedGuarded (dart:async/zone.dart:1851:12)
E/flutter (17451): #19 _runMainZoned. (dart:ui/hooks.dart:141:5)
E/flutter (17451): #20 _delayEntrypointInvocation. (dart:isolate-patch/isolate_patch.dart:283:19)

there's something wrong with the picture's fit.

Describe the bug
i wanna make the image full in sized of container but it's show me that just like the screenshot i put.i don't know why?when i set BoxFit.cover or BoxFit.contain to it i still get same situations...please help

To Reproduce
icon:Container( decoration: BoxDecoration(borderRadius: BorderRadius.circular(5),border: Border.all(color: colorScheme.onTertiary,width: 1),), child: v2timFriendInfo.userProfile!.faceUrl!.isNotEmpty? Container( decoration: BoxDecoration(borderRadius: BorderRadius.circular(8),color: Colors.transparent), clipBehavior: Clip.antiAlias, child: PowerImage.network("${v2timFriendInfo.userProfile!.faceUrl}",width: widget.size??48,height: widget.size??48,fit: BoxFit.cover), ) :PowerImage.asset("assets/images/mine/user.png",width: widget.size??48,height: widget.size??48,renderingType:renderingTypeExternal), ),

Expected behavior
picture can full of in the container

Screenshots
If applicable, add screenshots to help explain your problem.
image
image
image

Versions (please complete the following information):

  • Device: [android nox simulator]
  • OS: [e.g. iOS8.1]
  • flutter doctor -v:
  • power_image: 0.1.0-pre.2
  • power_image_ext: 3.0.0

Additional context
Add any other context about the problem here.

after hot restart serveral time while debuging will cause crash

Describe the bug
after hot restart serveral time while debuging will cause crash,I have encountered this issue for many time.
sometimes the log show out of memory,but this time show like as below

* thread #42, queue = 'com.hackemist.SDImageCache', stop reason = EXC_RESOURCE RESOURCE_TYPE_MEMORY (limit=2098 MB, unused=0x0)
    frame #0: 0x00000001a2dafde4 vImage`vConvert_16Q12to16F_vec + 208
vImage`vConvert_16Q12to16F_vec:
->  0x1a2dafde4 <+208>: stp    q4, q3, [x16]
    0x1a2dafde8 <+212>: ldp    q3, q2, [x1, #0x20]
    0x1a2dafdec <+216>: sshll.4s v4, v3, #0x0
    0x1a2dafdf0 <+220>: scvtf.4s v4, v4
Target 0: (Runner) stopped.
Lost connection to device.

To Reproduce
Steps to reproduce the behavior:
configured like the test demo and have replace most of image widget with power_image;

void main() async {
  runZonedGuarded(
    () async {
      PowerImageBinding();
      ...
      PowerImageLoader.instance.setup(
        PowerImageSetupOptions(
          renderingTypeTexture,
          errorCallbackSamplingRate: null,
          errorCallback: (PowerImageLoadException exception) {
            LogUtils.error(
              'Caught PowerImageLoadException : $exception',
            );
          },
        ),
      );
      runApp(const MyApp());
    },
    (Object error, StackTrace stackTrace) async {
     ...
    },
  );
}

Expected behavior
please dont crash that often 😅,

Screenshots
If applicable, add screenshots to help explain your problem.
image

Versions (please complete the following information):

  • Device: iPhone11
  • OS: ios15.3
  • flutter doctor -v:
展开查看 flutter doctor details

[✓] Flutter (Channel stable, 2.10.5, on macOS 12.4 21F79 darwin-x64, locale
    zh-Hans-CN)
    • Flutter version 2.10.5 at /Users/kangkang/Documents/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 5464c5bac7 (7 weeks ago), 2022-04-18 09:55:37 -0700
    • Engine revision 57d3bac3dd
    • Dart version 2.16.2
    • DevTools version 2.9.2
    • Pub download mirror https://pub.flutter-io.cn
    • Flutter download mirror https://storage.flutter-io.cn

[✓] Android toolchain - develop for Android devices (Android SDK version
32.1.0-rc1)
• Android SDK at /Users/kangkang/Library/Android/sdk
• Platform android-32, build-tools 32.1.0-rc1
• Java binary at: /Applications/Android
Studio.app/Contents/jre/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build
11.0.12+0-b1504.28-7817840)
• All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 13.2.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• CocoaPods version 1.11.3

[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.2)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build
11.0.12+0-b1504.28-7817840)

[✓] VS Code (version 1.67.2)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.42.0

[✓] Connected device (2 available)
• iPhone 11 (mobile) • 00008030-00010D3826E0802E • ios • iOS 15.3
19D50
• Chrome (web) • chrome • web-javascript • Google
Chrome 102.0.5005.61

[!] HTTP Host Availability
✗ HTTP host https://maven.google.com/ is not reachable. Reason: An error occurred while
checking the HTTP host: Operation timed out

! Doctor found issues in 1 category.

  • power_image Version: ^0.1.0-pre.2
  • power_image_ext Version: ^3.0.0

Additional context

能否考虑支持一下多引擎场景

目前业务使用的是flutter多引擎的模式,尝试修改方案。解决了多引擎下通信的问题,但是还有会偶现奔溃问题。目前没有头绪了。
image

PowerImage rotating images

Describe the bug
When using Power Image the Image gets displayed rotated.
I also checked the Image on my computer and it opens in expected format, also in browser. Just not with power image.
I tried PowerImage.network and PowerImage.file:

PowerImage.file(widget.file!.path,fit: BoxFit.fitHeight, renderingType: renderingTypeExternal,errorBuilder: (,,) => ErrorStoryWidget()))

Screenshots
If applicable, add screenshots to help explain your problem.

Versions (please complete the following information):

  • Device: [Iphone 12 Pro Max]
  • OS: [Ios 16]
  • flutter doctor -v:
    [✓] Flutter (Channel stable, 3.0.4, on macOS 12.6 21G115 darwin-x64, locale de-DE)
    • Flutter version 3.0.4 at /Users/sobhihammoud/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 85684f9300 (3 months ago), 2022-06-30 13:22:47 -0700
    • Engine revision 6ba2af10bb
    • Dart version 2.17.5
    • DevTools version 2.12.2

[!] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
• Android SDK at /Users/sobhihammoud/Library/Android/sdk
✗ cmdline-tools component is missing
Run path/to/sdkmanager --install "cmdline-tools;latest"
See https://developer.android.com/studio/command-line for more details.
✗ Android license status unknown.
Run flutter doctor --android-licenses to accept the SDK licenses.
See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.

[✓] Xcode - develop for iOS and macOS (Xcode 14.0.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• CocoaPods version 1.11.3

[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.2)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)

[✓] Android Studio (version 4.2)
• Android Studio at /Users/sobhihammoud/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/202.7351085/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264)

[✓] IntelliJ IDEA Ultimate Edition (version 2021.1.2)
• IntelliJ at /Users/sobhihammoud/Applications/JetBrains Toolbox/IntelliJ IDEA Ultimate.app
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart

[✓] IntelliJ IDEA Ultimate Edition (version 2021.1.2)
• IntelliJ at /Users/sobhihammoud/Library/Application Support/JetBrains/Toolbox/apps/IDEA-U/ch-0/211.7442.40/IntelliJ IDEA.app
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart

[✓] VS Code (version 1.71.2)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.48.0

[✓] Connected device (5 available)
• sdk gphone64 x86 64 (mobile) • emulator-5554 • android-x64 • Android 13 (API 33) (emulator)
• iPhoneS (mobile) • 00008101-001E4DA20A29003A • ios • iOS 16.0 20A362
• iPad von Sobhi (2) (mobile) • 00008027-001550490131802E • ios • iOS 15.5 19F77
• macOS (desktop) • macos • darwin-x64 • macOS 12.6 21G115 darwin-x64
• Chrome (web) • chrome • web-javascript • Google Chrome 105.0.5195.125

[✓] HTTP Host Availability
• All required HTTP hosts are available

! Doctor found issues in 1 category.

  • power_image Version: ^0.1.0-pre.2
  • power_image_ext Version: 2.5.3

Additional context
Attaching Screenshots
IMG_6343
IMG_6344
354c81b8-e394-4cfc-a1db-106399dc411e

6b5dc37f-41f3-4b13-a783-b2e1ffeac4c4

PowerImageLoader for network has not been registered.

E/MethodChannel#power_image/method(26251): Failed to handle method call
E/MethodChannel#power_image/method(26251): java.lang.IllegalStateException: PowerImageLoader for network has not been registered.
E/MethodChannel#power_image/method(26251): at com.taobao.power_image.loader.PowerImageLoader.handleRequest(PowerImageLoader.java:35)
E/MethodChannel#power_image/method(26251): at com.taobao.power_image.request.PowerImageBaseRequest.performLoadImage(PowerImageBaseRequest.java:60)
E/MethodChannel#power_image/method(26251): at com.taobao.power_image.request.PowerImageBaseRequest.startLoading(PowerImageBaseRequest.java:55)
E/MethodChannel#power_image/method(26251): at com.taobao.power_image.request.PowerImageRequestManager.startLoadingWithArguments(PowerImageRequestManager.java:71)

PowerImageTextureRequest onLoadResult crash

Describe the bug
在onLoadResult逻辑中,执行textureEntry = textureRegistry.createSurfaceTexture(); 时有概率触发FlutterJNI is not attached to native 崩溃

To Reproduce
目前没有一定能复现的路径,该崩溃在APP的线上日志收集到,有可能的场景是用户正处于RTC通话的场景下,被通话页面遮挡的某个Flutter页面触发了异常的重建流程,这个过程中涉及到图片的加载,随后崩溃。

Screenshots
我们没有线上用户的截屏,目前可以看到的崩溃的堆栈如图
栈

现场

Versions (please complete the following information):

  • flutter doctor -v:
    [✓] Flutter (Channel stable, 3.7.12, on macOS 13.4.1 22F82 darwin-arm64, locale zh-Hans-CN)
    [✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    [✓] Xcode - develop for iOS and macOS (Xcode 14.3.1)
    [✓] Chrome - develop for the web
    [✓] Android Studio (version 2022.2)
    [✓] Connected device (3 available)
    [✓] HTTP Host Availability

  • power_image Version: [0.1.0-pre.2]

  • power_image_ext Version: [2.5.3]

使用 RepaintBoundary 生成图片失败

RepaintBoundary(
  key: _screenshotKey,
  child: PowerImage.network(
    'https://flutter.github.io/assets-for-api-docs/assets/widgets/owl.jpg',
    renderingType: renderingTypeTexture,
  ),
)

给不知道如何配置power_image 尤其是现在很多flutter项目默认使用swift和kotlin的同学的说明书

很多对原生比较陌生的同学在使用power_image前不知道如何配置,尤其是现在很多flutter项目默认使用swift和kotlin新建,加上power_image的demo在ios和android只作了oc和java的配置说明。

下面是对官方demo的补充,降低此插件的使用难度:

1.ios-swift

1.1 如果不打算自己定制自定义对应的加载器,请把example/ios/Runner/Biz整个文件夹直接复制到自己的ios项目Runner
1.2 在example/ios/Runner/Runner-Bridging-Header.h添加以下桥接头文件

#import "PowerImageNetworkImageLoader.h"
#import "PowerImageAssetsImageLoader.h"
#import "PowerImageFlutterAssertImageLoader.h"
#import "PowerImageFileImageLoader.h"

1.3 在example/ios/Runner/Podfile中添加依赖,然后在自己的项目ios路径下使用终端pod install

pod  'SDWebImage', '~> 5.0'

1.4 在example/ios/Runner/AppDelegate.swift的application方法中添加以下注册

...
import power_image ///请导入
import SDWebImage  ///请导入

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
      
    ///添加注册
    PowerImageLoader.sharedInstance().register(PowerImageNetworkImageLoader.init(), forType: kPowerImageImageTypeNetwork)

    PowerImageLoader.sharedInstance().register(PowerImageAssetsImageLoader.init(), forType: kPowerImageImageTypeNativeAsset)

    PowerImageLoader.sharedInstance().register(PowerImageFlutterAssertImageLoader.init(), forType: kPowerImageImageTypeAsset)

    PowerImageLoader.sharedInstance().register(PowerImageFileImageLoader.init(), forType: kPowerImageImageTypeFile)

    SDImageCacheConfig.default.maxMemoryCount = 20
      
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

2.android-kotlin

2.1 在app/build.gradle的android.buildType下添加以下依赖,然后点击sync now(需要以android module打开项目)

    dependencies {
        implementation 'com.github.bumptech.glide:glide:4.12.0'
        annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
    }

2.2 同样的不打算自定义的加载器,请把example/android/app/src/main/java/com/taobao/power_image_example/power_image_loader/整个文件夹和example/android/app/src/main/java/com/taobao/power_image_example/GlideMultiFrameImage.java直接复制到自己的app/src/main/kotlin/com/xxx/xxx/下(复制之后注意修改导入路径)

2.3 在android项目的app/src/main/kotlin/com/xxx/xxx/MainActivity.kt中添加注册加载器

...
import com.xxx.xxxx.power_image_loader.PowerImageFileLoader  ///注意路径
import com.xxx.xxxx.power_image_loader.PowerImageFlutterAssetLoader
import com.xxx.xxxx.power_image_loader.PowerImageNativeAssetLoader
import com.xxx.xxxx.power_image_loader.PowerImageNetworkLoader
import io.flutter.embedding.android.FlutterActivity

import com.taobao.power_image.loader.PowerImageLoader

class MainActivity: FlutterActivity() {
    @Override
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        ///添加注册
        PowerImageLoader.getInstance().registerImageLoader(
             PowerImageNetworkLoader(this.applicationContext), "network");
        PowerImageLoader.getInstance().registerImageLoader(
             PowerImageNativeAssetLoader(this.applicationContext), "nativeAsset");
        PowerImageLoader.getInstance().registerImageLoader(
             PowerImageFlutterAssetLoader(this.applicationContext), "asset");
        PowerImageLoader.getInstance().registerImageLoader(
             PowerImageFileLoader(this.applicationContext), "file");
    }
}

3.开始在flutter中添加注册,

void main(){
    ...
    ///添加初始化
    PowerImageBinding();
    ///添加全局power_image的加载方式
    PowerImageLoader.instance.setup(PowerImageSetupOptions(renderingTypeTexture,
        errorCallbackSamplingRate: null,
        errorCallback: (PowerImageLoadException exception) {}));

    runApp(const MyApp());
    ...
}

最后可以愉快使用这个超棒的插件了🥳

能否兼容一下Android Fresco图片加载框架

【问题描述】
因为公司用的是Fresco框架,目前已经解决了网络加载,本地file,Native资源加载,没有兼容的包括GIF加载和flutter资源加载显示

【建议方案】
希望能够给下兼容代码,或者给个指点意见

纹理ID 不会及时的回收吗

Flutter 页面 A 显示图片 A 在Flutter里面在打开 页面B 显示图片B ,回退回页面A ,图片B的纹理ID 没有释放 ,整个Flutter 页面释放的时候 才会释放 图片B的纹理ID

初始化启动就报错

[VERBOSE-2:ui_dart_state.cc(209)] Unhandled Exception: 'package:flutter/src/foundation/binding.dart': Failed assertion: line 55 pos 12: '!_debugInitialized': is not true. #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39) #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5) #2 new BindingBase (package:flutter/src/foundation/binding.dart:55:12) #3 new _WidgetsFlutterBinding&BindingBase&GestureBinding (package:flutter/src/widgets/binding.dart) #4 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding (package:flutter/src/widgets/binding.dart) #5 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding (package:flutter/src/widgets/binding.dart) #6 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&PaintingBinding (package:flutter/src/widgets/binding.dart) #7 new _WidgetsFlutterBinding&BindingBase&GestureBinding&SchedulerBinding&ServicesBinding&P<…>

`
[✓] Flutter (Channel stable, 2.5.3, on macOS 12.1 21C52 darwin-arm, locale zh-Hans-CN)
• Flutter version 2.5.3 at /Users/Documents/work/softwork/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 18116933e7 (8 months ago), 2021-10-15 10:46:35 -0700
• Engine revision d3ea636dc5
• Dart version 2.14.4
• Pub download mirror https://pub.flutter-io.cn
• Flutter download mirror https://storage.flutter-io.cn

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
• Android SDK at /Users/jack/Library/Android/sdk
• Platform android-31, build-tools 30.0.3
• ANDROID_HOME = /Users/Library/Android/sdk
• Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264)
• All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS
• Xcode at /Applications/Xcode.app/Contents/Developer
• Xcode 13.1, Build version 13A1030d
• CocoaPods version 1.11.3

[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.2)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
• Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264)

[✓] VS Code (version 1.55.2)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.22.0

[✓] Connected device (3 available)
• iPhone 13 Pro (mobile) • FA12CED7-A7E5-4978-8DA3-203FE47AEDA9 • ios • com.apple.CoreSimulator.SimRuntime.iOS-15-0 (simulator)
• macOS (desktop) • macos • darwin-arm64 • macOS 12.1 21C52 darwin-arm
• Chrome (web) • chrome • web-javascript • Google Chrome 102.0.5005.61

`

是否能与EngineGroup配合使用?

项目使用EngineGroup,有时候会出现图片显示不出来的问题,看实现里面有很多的单例,是否需要配合FlutterBoost或者只能关闭EngineGroup?

mark

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Versions (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • flutter doctor -v:
  • power_image Version: [e.g. 0.1.0]
  • power_image_ext Version: [e.g. 2.5.3]

Additional context
Add any other context about the problem here.

请尽快适配Flutter3.16

Flutter升级3.16后使用example报错:
rror: ../lib/src/common/power_image_provider.dart:41:53: Error: Type 'DecoderCallback' not found.
ImageStreamCompleter load(PowerImageProvider key, DecoderCallback? decode) {
^^^^^^^^^^^^^^^
../lib/src/common/power_image_provider.dart:49:31: Error: Type 'DecoderCallback' not found.
PowerImageProvider key, DecoderCallback? decode) async {
^^^^^^^^^^^^^^^
../lib/src/common/power_image_provider.dart:41:53: Error: 'DecoderCallback' isn't a type.
ImageStreamCompleter load(PowerImageProvider key, DecoderCallback? decode) {
^^^^^^^^^^^^^^^
../lib/src/common/power_image_provider.dart:49:31: Error: 'DecoderCallback' isn't a type.
PowerImageProvider key, DecoderCallback? decode) async {
^^^^^^^^^^^^^^^

像这种分辨率超级大的图片加载不出来啊,内存也相当的高。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.