Anti-aliased image rendering

This commit is contained in:
Laurenz 2022-06-14 17:20:31 +02:00
parent 7a6c2cce77
commit 20b990d297
15 changed files with 19 additions and 16 deletions

View File

@ -2,6 +2,7 @@
use std::io::Read; use std::io::Read;
use image::imageops::FilterType;
use image::{GenericImageView, Rgba}; use image::{GenericImageView, Rgba};
use tiny_skia as sk; use tiny_skia as sk;
use ttf_parser::{GlyphId, OutlineBuilder}; use ttf_parser::{GlyphId, OutlineBuilder};
@ -351,33 +352,35 @@ fn render_image(
let view_width = size.x.to_f32(); let view_width = size.x.to_f32();
let view_height = size.y.to_f32(); let view_height = size.y.to_f32();
let pixmap = match img { let aspect = (img.width() as f32) / (img.height() as f32);
let scale = ts.sx.max(ts.sy);
let w = (scale * view_width.max(aspect * view_height)).ceil() as u32;
let h = ((w as f32) / aspect).ceil() as u32;
let mut pixmap = sk::Pixmap::new(w, h)?;
match img {
Image::Raster(img) => { Image::Raster(img) => {
let w = img.buf.width(); let downscale = w < img.width();
let h = img.buf.height(); let filter = if downscale {
let mut pixmap = sk::Pixmap::new(w, h)?; FilterType::Lanczos3
for ((_, _, src), dest) in img.buf.pixels().zip(pixmap.pixels_mut()) { } else {
FilterType::CatmullRom
};
let buf = img.buf.resize(w, h, filter);
for ((_, _, src), dest) in buf.pixels().zip(pixmap.pixels_mut()) {
let Rgba([r, g, b, a]) = src; let Rgba([r, g, b, a]) = src;
*dest = sk::ColorU8::from_rgba(r, g, b, a).premultiply(); *dest = sk::ColorU8::from_rgba(r, g, b, a).premultiply();
} }
pixmap
} }
Image::Svg(Svg(tree)) => { Image::Svg(Svg(tree)) => {
let size = tree.svg_node().size;
let aspect = (size.width() / size.height()) as f32;
let scale = ts.sx.max(ts.sy);
let w = (scale * view_width.max(aspect * view_height)).ceil() as u32;
let h = ((w as f32) / aspect).ceil() as u32;
let mut pixmap = sk::Pixmap::new(w, h)?;
resvg::render( resvg::render(
&tree, &tree,
FitTo::Size(w, h), FitTo::Size(w, h),
sk::Transform::identity(), sk::Transform::identity(),
pixmap.as_mut(), pixmap.as_mut(),
); )?;
pixmap
} }
}; }
let scale_x = view_width / pixmap.width() as f32; let scale_x = view_width / pixmap.width() as f32;
let scale_y = view_height / pixmap.height() as f32; let scale_y = view_height / pixmap.height() as f32;
@ -386,7 +389,7 @@ fn render_image(
paint.shader = sk::Pattern::new( paint.shader = sk::Pattern::new(
pixmap.as_ref(), pixmap.as_ref(),
sk::SpreadMode::Pad, sk::SpreadMode::Pad,
sk::FilterQuality::Bilinear, sk::FilterQuality::Nearest,
1.0, 1.0,
sk::Transform::from_scale(scale_x, scale_y), sk::Transform::from_scale(scale_x, scale_y),
); );

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 KiB

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 55 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB