Sittiphan Sittisak
Sittiphan Sittisak

Reputation: 885

Flutter web build with canvaskit: Failed to load Image.network()

I can't use the image URL from my domain but I can use the image URL from another domain like Facebook. The error is: enter image description here

enter image description here

It happened when putting the image URL from StackOverflow in the Image.network() too. For example, try using the picture above(Image.network('https://i.sstatic.net/o6lwE.png')).

The basic method for fixing is rendered with HTML(flutter run -d chrome --web-renderer html) but I need to use the toImage() function and rendering with HTML doesn't support this function. So I render with Canvaskit.

This link(https://docs.flutter.dev/development/platform-integration/web-images#host-your-images-in-a-cors-enabled-cdn) can help someone who is using the Firebase but I am using the Ubuntu with the Apache.

Actually, I want to render with HTML because after rendering with Canvaskit I encountered a lot of problems.

Render with HTML case: If there is a function that can be used instead of the toImage() function, please tell me.

Render with Canvaskit case: If you know how to display the image URL with Image.network(), please tell me.

Thank you.

Upvotes: 5

Views: 5906

Answers (2)

Yauheni Prakapenka
Yauheni Prakapenka

Reputation: 1714

I'm using canvaskit rendering for web. When trying to display an image by url:

Image.network(banner.imageUrl)

I get the error: Another exception was thrown: [object ProgressEvent]

I solved the problem with the package from pub.dev: image_network

My solution:

import 'package:flutter/material.dart';
import 'package:image_network/image_network.dart';

/// Supports canvaskit rendering for web.
class AppNetworkImage extends StatelessWidget {
  final String imageUrl;

  const AppNetworkImage({
    super.key,
    required this.imageUrl,
  });

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints constraints) {
        return ImageNetwork(
          image: imageUrl,
          height: constraints.maxHeight,
          width: constraints.maxWidth,
          duration: 100,
          onPointer: true,
          onLoading: const SizedBox(),
        );
      },
    );
  }
}

Upvotes: 0

Sittiphan Sittisak
Sittiphan Sittisak

Reputation: 885

This question was closed by the auto system of StackOverflow, So I delete it and create a new one.

After 2 days, that's what I found.

  1. Use https://cors-anywhere.herokuapp.com/ or create your proxy.
  1. Use HtmlElementView(viewType: '$imageUrl').
  • Add this in analysis_options.yaml at the bottom.
analyzer:
  errors:
    undefined_prefixed_name: ignore
  • Import these in your dart file.
import 'dart:html';
import 'dart:ui' as ui;
  • Add this in the initState() or Widget build(), this has to use before - Your image widget looks like this:
ui.platformViewRegistry.registerViewFactory(
      $imageUrl,
      (int viewId) => ImageElement()
        ..style.width = 'auto' //or '0%'-'100%'
        ..style.height = 'auto' //or '0%'-'100%'
        ..src = $imageUrl,
    );
  • Your image widget looks like this:
HtmlElementView(viewType: $imageUrl)
  1. Use .htaccess
  • Activated .htacess by open /etc/apache2/apache2.conf in <Directory /var/www/> tag, change AllowOverride None to AllowOverride All.
  • You have to enable mod_headers by typing these in the console. Enable mod_headers with a2enmod headers then restart apache with sudo service apache2 restart.
  • Create your .htaccess in your root(For me, in the HTML folder)
  • Allowing cross-origin use of images and canvas by adding this in the .htaccess file.
<IfModule mod_setenvif.c>
  <IfModule mod_headers.c>
    <FilesMatch "\.(avifs?|bmp|cur|gif|ico|jpe?g|jxl|a?png|svgz?|webp)$">
      SetEnvIf Origin ":" IS_CORS
      Header set Access-Control-Allow-Origin "*" env=IS_CORS
    </FilesMatch>
  </IfModule>
</IfModule>

In my opinion:

  • Method 1 is easy and quick to fix. but temporarily available and limited (https://github.com/Rob--W/cors-anywhere/issues/301) and slower than other methods because the app has to connect with this link and the link will get your image URL and then send it back to your app. If I create the web looks like this, it will break because too many users use it, right?
  • Method 2 is suitable for images that are on other domains. But the disadvantage is that it is difficult to determine the width and height of the image. It is necessary to check which side length is the longest to set this ..style. *longest * is '100%' and the shorter side is 'auto'.
  • Method 3 is suitable for people who use images on their domain.

It would be nice to have a package that completes things like method 2.

You can try your imageUrl at: https://flutter-test-exam-bug.web.app/#/stackoverflow_72306043

For testing on the local side for the Flutter web (Canvaskit), follow this

Upvotes: 3

Related Questions