Как исправить трепетание холста.Нарисуйте изображение размытого контура

#flutter #custom-painter

Вопрос:

Я использую пользовательский художник вместе с canvas.drawImageRect для рисования областей изображения. (Полный код ниже). Моя проблема в том, что контур моего изображения всегда размыт или смешан:

введите описание изображения здесь

Этот снимок сделан из эмулятора. При масштабировании видно, что 2 краевых пикселя прямоугольника изображения смешаны с фоном — они имеют голубоватый оттенок. Результат аналогичен на физическом устройстве, разница в том, что у меня размыто около 4 краевых пикселей вместо 2.

Как я могу получить четкую границу для своего изображения без какого-либо смешивания фона?

Спасибо!

Код ниже:

 import 'package:flutter/material.dart';
import 'package:network_to_file_image/image_for_canvas.dart';
import 'package:network_to_file_image/network_to_file_image.dart';
import 'dart:ui' as ui;

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    var myWidth = MediaQuery.of(context).size.width;

    User user = User(
      filename: null,
      url: "https://homepages.cae.wisc.edu/~ece533/images/baboon.png",
    );

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Container(
          width: myWidth,
          height: myWidth,
          child: CustomPaint(
              painter: ImagePainter(user, loadCallback: (_, __, ___) {
            setState(() {});
          }))),
    );
  }
}

class ImagePainter extends CustomPainter {
  final User user;
  final LoadCallback<User> loadCallback;

  ImagePainter(
    this.user, {
    required this.loadCallback,
  });

  @override
  void paint(Canvas canvas, Size size) {
    canvas.save();
    canvas.drawRect(Rect.fromLTWH(0, 0, size.width, size.height),
        Paint()..color = Colors.blue);
    canvas.restore();

    var imageForCanvas = _imageForCanvas();
    ui.Image? image = imageForCanvas.image(user);

    if (image != null) {
      canvas.save();
      canvas.drawImageRect(
        image,
        Rect.fromLTWH(
          12,
          12,
          256,
          256,
        ),
        Rect.fromLTWH(
          50,
          50,
          size.width - 100,
          size.height - 100,
        ),
        Paint()
      );
      canvas.restore();
    }
  }

  ImageForCanvas<User> _imageForCanvas() => ImageForCanvas<User>(
        imageProviderSupplier: (User user) => NetworkToFileImage(
          file: null,
          url: user.url,
        ),
        keySupplier: (User user) => user.url!,
        loadCallback: loadCallback,
      );

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

class User {
  final String? filename;
  final String? url;

  User({
    this.filename,
    this.url,
  });
}
 

А вот pubspec.yaml:

 name: reporo
description: A new Flutter project.
version: 1.0.0 1

environment:
  sdk: ">=2.12.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  network_to_file_image: ^3.0.0

  cupertino_icons: ^1.0.2

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter:
  uses-material-design: true
 

Комментарии:

1. проверять Paint.filterQuality

2. кстати, зачем тебе этот халтурщик ImagePainter.loadCallback ? вы не можете просто передать изображение непосредственно в ImagePainter конструктор?

3. @pskink, обратный вызов-это требование библиотеки network_to_fileimage, которую я использую для загрузки изображений и преобразования их во что-то, что я могу использовать для рисования на холсте. Вероятно, есть лучшие способы сделать это, просто быстро набросал минимальное воспроизведение для моей проблемы 🙂

4. @pskink уже перепробовал все возможные значения для качества фильтра, ничего не меняет