#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 уже перепробовал все возможные значения для качества фильтра, ничего не меняет