baseflow / octo_image Goto Github PK
View Code? Open in Web Editor NEWA multifunctional Flutter image widget
Home Page: https://baseflow.com/
License: MIT License
A multifunctional Flutter image widget
Home Page: https://baseflow.com/
License: MIT License
Make gaplessPlayback fade from one image to the next
OctoImage support nicely fading from placeholder to image, but it doesn't fade from one image to the next
Make gaplessPlayback fade the image from one to the next just like the placeholder fades.
Error after removing image which result in crash if route with deleted image widget is popped
log.txt
No errors
Delete image widget from list AutomaticAnimatedListView
of library great_list_view
Error also can be reproduced with cached_network_image
. DioImage implementation is copied from here because it depends on previous major version of dio
Version: 1.0.2
โข Flutter version 3.7.3 on channel stable at /Users/vovchara/Documents/flutter
โข Upstream repository https://github.com/flutter/flutter.git
โข Framework revision 9944297138 (10 days ago), 2023-02-08 15:46:04 -0800
โข Engine revision 248290d6d5
โข Dart version 2.19.2
โข DevTools version 2.20.1
[โ] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
โข Android SDK at /Users/vovchara/Library/Android/sdk
โข Platform android-33, build-tools 33.0.0
โข 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.2)
โข Xcode at /Applications/Xcode.app/Contents/Developer
โข Build 14C18
โข 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.1)
โข VS Code at /Applications/Visual Studio Code.app/Contents
โข Flutter extension version 3.58.0
[โ] Connected device (2 available)
โข macOS (desktop) โข macos โข darwin-arm64 โข macOS 13.2.1 22D68 darwin-arm64
โข Chrome (web) โข chrome โข web-javascript โข Google Chrome 110.0.5481.100
[โ] HTTP Host Availability
โข All required HTTP hosts are available
โข No issues found!
Platform:
/C:/Users/sksso/AppData/Local/Pub/Cache/hosted/pub.dev/flutter_blurhash-0.7.0/lib/src/blurhash_widget.dart(218,42): error G5FE39F1E: Type 'DecoderCallback' not found. [E:\sksmarket\sksmarket\build\windows\flutter\flutter_assemble.vcxproj]
Version: 1.x
Platform:
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:instagram/presentation/widgets/global/others/play_this_video.dart';
// ignore: depend_on_referenced_packages
import 'package:octo_image/octo_image.dart';
class NetworkDisplay extends StatefulWidget {
final int cachingHeight, cachingWidth;
final String url, blurHash;
final double aspectRatio;
final bool isThatImage;
final double? height;
final double? width;
const NetworkDisplay({
Key? key,
required this.url,
this.isThatImage = true,
this.cachingHeight = 720,
this.cachingWidth = 720,
this.height,
this.width,
this.blurHash = "",
this.aspectRatio = 0.0,
}) : super(key: key);
@OverRide
State createState() => _NetworkDisplayState();
}
class _NetworkDisplayState extends State {
@OverRide
void initState() {
super.initState();
}
@OverRide
void didChangeDependencies() {
if (widget.isThatImage && widget.url.isNotEmpty) {
precacheImage(NetworkImage(widget.url), context);
}
super.didChangeDependencies();
}
@OverRide
Widget build(BuildContext context) {
return widget.aspectRatio == 0 ? whichBuild(height: null) : aspectRatio();
}
Widget aspectRatio() {
return AspectRatio(
aspectRatio: widget.aspectRatio,
child: whichBuild(),
);
}
Widget whichBuild({double? height = double.infinity}) {
return !widget.isThatImage
? PlayThisVideo(
play: true,
videoUrl: widget.url,
blurHash: widget.blurHash,
)
: buildOcto(height);
}
Widget buildOcto(height) {
int cachingHeight = widget.cachingHeight;
int cachingWidth = widget.cachingWidth;
if (widget.aspectRatio != 1 && cachingHeight == 720) cachingHeight = 960;
return OctoImage(
image: CachedNetworkImageProvider(widget.url,
maxWidth: cachingWidth, maxHeight: cachingHeight),
errorBuilder: (context, url, error) => buildError(),
fit: BoxFit.cover,
width: widget.width ?? double.infinity,
height: widget.height ?? height,
placeholderBuilder: widget.blurHash.isNotEmpty
? OctoPlaceholder.blurHash(widget.blurHash, fit: BoxFit.cover)
: (context) => Center(child: loadingWidget()),
);
}
SizedBox buildError() {
return SizedBox(
width: double.infinity,
height: widget.aspectRatio,
child: Icon(Icons.warning_amber_rounded,
size: 30, color: Theme.of(context).focusColor),
);
}
Widget loadingWidget() {
double aspectRatio = widget.aspectRatio;
return aspectRatio == 0
? buildSizedBox()
: AspectRatio(
aspectRatio: aspectRatio,
child: buildSizedBox(),
);
}
Widget buildSizedBox() {
return Container(
width: double.infinity,
color: Theme.of(context).textTheme.bodyMedium!.color,
child: Center(
child: CircleAvatar(
radius: 57,
backgroundColor: Theme.of(context).textTheme.bodySmall!.color,
child: Center(
child: CircleAvatar(
radius: 56,
backgroundColor: Theme.of(context).textTheme.bodyMedium!.color,
)),
)),
);
}
}
How i can Solve this problem please
Great package!
Sometimes it is also valuable to obtain the imageprovider in the imageBuilder constructor.
Currently it looks like this:
typedef OctoImageBuilder = Widget Function(BuildContext context, Widget child);
Hence I'd like it changed to
typedef OctoImageBuilder = Widget Function(BuildContext context, Widget child, Imageprovider image);
Had a look at CachedNetworkImage, and did a workaround:
ImageProvider imageProvider =...
return OctoImage(
image: imageProvider,
...
imageBuilder: (context, _) => here i'm using the imageProvider
);
but would be more slick to have the imageprovider directly in the imageBuilder's constructor
When using Image.asset
with BoxFit cover as placeholder or error builders, the fit is applied correctly. (On cached_network_image v2.2.0)
The specified BoxFit for the placeholder and error builders is not applied.
Simple example. In a real scenario the placeholder would be an Image.asset widget, but this is enough to see the regression.
Container(
color: Colors.red,
child: OctoImage(
image: NetworkImage('...'),
placeholderBuilder: (context) {
return Image.network(
"https://blurha.sh/assets/images/img1.jpg",
fit: BoxFit.cover,
);
},
errorBuilder: (context, e, s) {
return Image.network(
"https://blurha.sh/assets/images/img1.jpg",
fit: BoxFit.cover,
);
},
fit: BoxFit.cover,
height: 100,
width: 100,
),
),
Version: 0.2.1
I got an issue with OOM on a very low device with random crashes. After investigation, I figure out that the problem with ImageHandler was reassigned.
Why did it happen?
Because in _OctoImageState
in didUpdateWidget
method each time reassign previous handler and saves current as well because of placeholder + progressBuilder
properties. So in time, you have a situation where during the build method code executes build for all prev handlers and request all the images in the hierarchy(for 12 images on screen after 1 min with 10-sec delay of changing URL have 60 sec/10 delay =6 requests for each image + decoding job which cause the crash).
Fix proposal
Instead of each time reassigning handler need to create a new handler for the previous state without a placeholder and progress from the current handle or provide a way how to clear prev handler
instead of
_previousHandler = _imageHandler;
Need to recreate ImageHandler without placeholder from current ImageHandler
_previousHandler = ImageHandler(
image: oldWidget.image,
imageBuilder: oldWidget.imageBuilder,
placeholderBuilder: oldWidget.placeholderBuilder,
progressIndicatorBuilder: oldWidget.progressIndicatorBuilder,
errorBuilder: oldWidget.errorBuilder,
placeholderFadeInDuration: oldWidget.placeholderFadeInDuration,
fadeOutDuration: oldWidget.fadeOutDuration,
fadeOutCurve: oldWidget.fadeOutCurve,
fadeInDuration: oldWidget.fadeInDuration,
fadeInCurve: oldWidget.fadeInCurve,
fit: oldWidget.fit,
width: oldWidget.width,
height: oldWidget.height,
alignment: oldWidget.alignment,
repeat: oldWidget.repeat,
color: oldWidget.color,
colorBlendMode: oldWidget.colorBlendMode,
matchTextDirection: oldWidget.matchTextDirection,
filterQuality: oldWidget.filterQuality,
);
This issue is not related to Flutter 3.x. It's reproducible on 2.10.3 and 3.x.
I also saw a couple of old issues with CachableImage on flutter GitHub, and I think that can be a root cause of crashes
Using OctoImage with the new CanvasKit Skia support seems to result in
Another exception was thrown: Expected a value of type 'SkImage', but got one of type 'HtmlImage'
exceptions. I'm still investigating, just asking if you already tried it.
RESOLVED: Fixed in Flutter master branch on 18th of May 2020
getting below in logs with below example:
return OctoImage(
image: CachedNetworkImageProvider(url),
placeholderBuilder: (context) =>
context.watch<ThemeProvider>().isLightTheme
? CircularProgressIndicator(
backgroundColor: Theme.of(context).primaryColor,
valueColor: const AlwaysStoppedAnimation(Colors.white),
)
: CircularProgressIndicator(
backgroundColor: Theme.of(context).primaryColor,
),
errorBuilder: (context, url, dynamic error) => _sizedContainer(
Icon(
Icons.error,
color: Colors.red,
),
),
);
โโโโโโโโ Exception caught by image resource service โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The following assertion was thrown when reporting an error to an image listener:
setState() called after dispose(): _ImageState#8fa88(lifecycle state: defunct, not mounted, stream: ImageStream#ebcf8(MultiFrameImageStreamCompleter#209a4, [960ร720] @ 1.0x, 1 listener), pixels: null, loadingProgress: null, frameNumber: null, wasSynchronouslyLoaded: false)
This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer includes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback.
The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" property of this object before calling setState() to ensure the object is still in the tree.
This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State object after it has been removed from the tree. To avoid memory leaks, consider breaking the reference to this object during dispose().
When the exception was thrown, this was the stack:
#0 State.setState.<anonymous closure> (package:flutter/src/widgets/framework.dart:1197:9)
#1 State.setState (package:flutter/src/widgets/framework.dart:1232:6)
#2 _ImageState._getListener.<anonymous closure> (package:flutter/src/widgets/image.dart:1116:13)
#3 ImageStreamCompleter.reportError (package:flutter/src/painting/image_stream.dart:504:24)
#4 ImageStreamCompleter.setImage (package:flutter/src/painting/image_stream.dart:439:9)
...
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโ Exception caught by image resource service โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
setState() called after dispose(): _ImageState#b0bda(lifecycle state: defunct, not mounted, stream: ImageStream#6f11d(MultiFrameImageStreamCompleter#366d4, [1632ร1224] @ 1.0x, 1 listener), pixels: null, loadingProgress: null, frameNumber: null, wasSynchronouslyLoaded: false)
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Due to some needs of the project, we need to monitor the loading time of pictures, not only downloading, including decoding. That is, we need to know how many times to display a set of pictures, from the begin loading to render complete (rendering monitoring may be difficult, then use the decoding completion time is ok) .
I think the property _isLoaded of ImageHandler is very useful, how to expose it. Actually, we want to use(or get) it in CachedNetworkImage
I'm sure you are aware of the various problems with inkwell effects on images. What's your preferred solution with respect to Octoimage? Maybe could include an option to include the Image as Ink.Image rather than the normal Image(....)?
Or, as I mentioned in my separate request, provide the imageprovider in the imagebuilder constructor and allow the user to do this him/her-self?
Size is infinite although width and or height are set.
I expect the widget to adhere to the width and height that are set.
Leading widget consumes entire tile width. Please use a sized widget.
'package:flutter/src/material/list_tile.dart':
Failed assertion: line 1353 pos 7: 'tileWidth != leadingSize.width'
I have the image inside a ListTile like this:
ListTile(
contentPadding: EdgeInsets.only(
left: 4.0, right: 8.0, top: 4.0, bottom: 4.0),
leading: CachedNetworkImage(
imageUrl:
"https://www.themealdb.com/images/ingredients/" +
Uri.encodeComponent(item.title) +
".png",
placeholder: (context, url) =>
CircularProgressIndicator(),
errorWidget: (context, url, error) => Icon(Icons.error),
fit: BoxFit.fill,
width: 32,
height: 32,
),
title: Text(item.title, style: Styles.listText),
trailing: Icon(Icons.add),
onTap: () {
Navigator.of(context).pop();
}),
From: Baseflow/flutter_cached_network_image#273 (comment)
Version: 0.2.0
Platform:
Minimal reproducible sample with OctoImage(checked iOS only)
On the latest beta channel.
What is more interesting on 1.22.0-12.1.pre everything was fine.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:octo_image/octo_image.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int index = 0;
@override
void initState() {
super.initState();
Timer.periodic(
Duration(seconds: 2),
(timer) {
setState(() {
++index;
});
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: OctoImage(
image:
NetworkImage('https://via.placeholder.com/300.png/09f/fff?index=$index'),
imageBuilder: (_, image) => image,
placeholderBuilder: (_) => Container(color: Colors.red),
gaplessPlayback: true,
),
);
}
}
[โ] Flutter (Channel beta, 1.26.0-17.6.pre, on macOS 11.2.1 20D75 darwin-x64, locale en)
โข Flutter version 1.26.0-17.6.pre at /Users/yauhen_sampir/fvm/versions/beta
โข Framework revision a29104a69b (9 days ago), 2021-02-16 09:26:56 -0800
โข Engine revision 21fa8bb99e
โข Dart version 2.12.0 (build 2.12.0-259.12.beta)
[โ] Android toolchain - develop for Android devices (Android SDK version 29.0.3)
โข Android SDK at /Users/yauhen_sampir/Library/Android/sdk
โข Platform android-30, build-tools 29.0.3
โข Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
โข Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495)
โข All Android licenses accepted.
[โ] Xcode - develop for iOS and macOS
โข Xcode at /Applications/Xcode.app/Contents/Developer
โข Xcode 12.4, Build version 12D4e
โข CocoaPods version 1.10.1
[โ] Chrome - develop for the web
โข Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[โ] Android Studio (version 4.1)
โข 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 1.8.0_242-release-1644-b3-6915495)
[โ] VS Code (version 1.53.2)
โข VS Code at /Applications/Visual Studio Code.app/Contents
โข Flutter extension version 3.9.0
Also can be reproduced using cached network image
package
Baseflow/flutter_cached_network_image#513
It seems blurhash has been removed - but the first example in the documentation still showcases how to use it:
OctoImage(
image: CachedNetworkImageProvider(
'https://blurha.sh/assets/images/img1.jpg'),
placeholderBuilder: OctoPlaceholder.blurHash(
'LEHV6nWB2yk8pyo0adR*.7kCMdnj',
),
errorBuilder: OctoError.icon(color: Colors.red),
fit: BoxFit.cover,
);
Yet there is no OctoPlacholder.blurHash(...)
method anymore. Please update the examples!
Version: 1.x
Platform:
For questions or help we recommend checking:
When we use FadeWidget with direction reverse and duration zero it is not disposing the child when the animation is completed.
The root cause of this issue is that animationController doesn't give callbacks to the listener when the duration is zero
Related Issue - Baseflow/flutter_cached_network_image#942
The widget should be disposed
We are able to reproduce this with the following code, where the blinkingRedDot widget never gets disposed
BlinkingRedDot is a inifnite is widget which blinks infinitely with a animation controller
FadeWidget(
child: BlinkingRedDot(),
direction: AnimationDirection.reverse,
duration: Duration(milliseconds: 0),
);
Version: 2.0.0
Platform:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.