-
Notifications
You must be signed in to change notification settings - Fork 3
Blurred image is grayed out, despite the input not being so #8
Comments
Have you tried using |
Nevermind. That's not the output of stackblur-iter, there's something going wrong in your pixel conversion code (or something else). Try using |
also reminds me I'm missing stride checks in Edit: fixed |
This is weird as hell. Are you sure you're passing the correct parameters to firefox_puXnUzewHB.mp4There's certainly nothing that could convert an image to grayscale. Each component is treated totally separately. |
As far as I can tell yes, gdk_pixbuf only has support for rgb as the colourspace (2nd param), the image doesn't have any alpha (3rd param), and it should have 8 bits per sample (4th param), I added these assertions after assert!(!pixbuf.has_alpha());
assert!(pixbuf.bits_per_sample() == 8); and the program continues to run, so I believe those params should be ok, and I believe the width, height, and rowstride should remain unaffected by the blur, so I think those params are fine too. I replaced the Lines 9 to 12 in 53be4ee
but with |
I'll look into it more soon, in the meantime see if removing the blur does anything? |
Looks like gdk pixbuf requires some C libraries and pkg-config. Ughhh. This is gonna be a pain Edit: Sorry, I cannot reproduce this yet. It looks like the only way to get the libraries I need is to install the entirety of GTK, which among other things, requires Python, X11, Perl, and a bunch of different build systems. Yes, those are apparently just the runtime dependencies!! Trying to install it, WTF I'm going to try this in Alpine where I can keep all this shit off my system, sorry for the wait. |
No worries |
Yeah okay I dunno wtf is going on but the first line of |
Nevermind that; random GitHub issue to the rescue. I know what the issue is. Because the stride is not a multiple of 3, the chunks_mut is getting thrown off. Because each row has its channels shifted by 1, the vertical part of stackblur essentially averages out the different channels, turning it grayscale. So it is your conversion code. Or well more accurately it's whatever retarded shit gdk pixbuf is doing. This version works: use std::io::Cursor;
use gdk_pixbuf::{Colorspace, Pixbuf};
use stackblur_iter::{blur_argb, imgref::ImgRefMut};
fn main() {
let pixbuf = Pixbuf::from_read(Cursor::new(include_bytes!("unknown.png"))).unwrap();
assert_eq!(pixbuf.n_channels(), 3);
let pixels = pixbuf.pixel_bytes().unwrap().to_vec();
let width = pixbuf.width() as usize;
let height = pixbuf.height() as usize;
let stride = pixbuf.rowstride() as usize;
let mut pixels = match pixbuf.n_channels() {
3 => blur_rgb(pixels, width, height, stride, 5),
_ => unreachable!(),
};
Pixbuf::from_mut_slice(
&mut pixels,
Colorspace::Rgb,
false,
8,
pixbuf.width(),
pixbuf.height(),
pixbuf.width() * 3,
)
.savev("blurred.png", "png", &[])
.unwrap();
}
fn blur_rgb(pixels: Vec<u8>, width: usize, height: usize, stride: usize, radius: usize) -> Vec<u8> {
assert_eq!(pixels.len() % 3, 0, "The pixel buffer's length should be a multiple of 3");
//assert_eq!(stride % 3, 0, "The pixel buffer's stride should be a multiple of 3");
let mut iter = pixels.into_iter();
let mut pixels = Vec::with_capacity(width * height);
for _ in 0..height {
for _ in 0..width {
pixels.push(u32::from_be_bytes([255, iter.next().unwrap(), iter.next().unwrap(), iter.next().unwrap()]));
}
for _ in 0..stride - width * 3 {
iter.next();
}
}
let mut img = ImgRefMut::new_stride(&mut pixels, width, height, stride / 3);
blur_argb(&mut img, radius);
pixels.into_iter().flat_map(|pixel| {
let [_, r, g, b] = pixel.to_be_bytes();
[r, g, b]
}).collect()
} Keep in mind it was produced in Here's the output: With all this in mind, if you inspect the original corrupted blur closely (specifically the one with stride), you can start to see the individual symptoms: |
Thank you so much! |
Personally I'd implore you to try things other than pixbuf, it's a huge dynamic library and if picking stride that isn't a multiple of channels isn't a sign of Sus quality, I don't know what is. If you just need something that works with multiple formats I would recommend In the future, check your invariants before reporting issues here :) asserting stride is a multiple of 3 would've let you know real fast what the issue is |
honestly it slipped my mind that the stride also had to be a multiple of 3 for that code to work 😅
I'm writing a gtk-rs based app so not using pixbuf wouldn't remove the huge dynamic library dependencies I have, though I do think I want to remove pixbuf from this code specifically, but I'll have to understand better how cairo imagesurfaces work. (for context, I'm writing a screenshot app for Linux because I'm dissatisfied with the existing ones, and decided to use your crate for the blur function of its editor) |
|
So I'm using your crate in my app and hitting an issue while trying to blur a
gdk_pixbuf::Pixbufs
, that is for certain images the blurred result is grayed out. I believe that it is related to the size of the image, but I'm not entirely too sure. This is an example that exhibits this issueAn example image and the result after the above program is ran
becomes
ran through the above program
Cargo.toml for the above program
The Pixbuf mentioned above stores its data in an
[rgb][rgb][rgb]...
format and I'm converting it to ARGB u32s as that's pretty convenient because it allows me to use theblur_argb
method provided by your crate and not have to write my own RGB type.For the record I don't believe this to be an issue with me using
0xff
for every alpha byte in the intermediary buffer as I replaced it with a randomly generated byte using therand
crate and the output didn't look like it changed.The text was updated successfully, but these errors were encountered: