Cropping a layer based on it's content
ok-nick opened this issue · 4 comments
I'm assuming this isn't currently supported and I was looking at a few dependencies that do, but they include a lot of other stuff outside of psd's scope.
I was planning on doing this externally, but would it cause further optimizations if done internally? Any pointers on how it could be done? My goal is to export a layer as a png, excluding any white space.
I'm currently using the layer.rgba()
method
Also quick question, how would you suggest exporting the return from layer.rgba()
as a png?
Here's a quick example of creating an image::DynamicImage
.
use image::{DynamicImage, GenericImage, Rgba};
use psd::Psd;
pub fn img_from_psd(psd: &Psd) -> DynamicImage {
let pixels = psd.rgba();
let pixel_count = pixels.len() / 4;
let mut img = DynamicImage::new_rgba8(psd.width(), psd.height());
for idx in 0..pixel_count {
let x = idx as u32 % psd.width();
let y = idx as u32 / psd.width();
let mut pixel = [0; 4];
let pixel_slice = &pixels[4 * idx..4 * idx + 4];
pixel.copy_from_slice(pixel_slice);
img.put_pixel(x, y, Rgba(pixel))
}
img
}
The image crate has methods for cropping as well as other image manipulation functions.
If you only need a PNG with no image manipulation you can also take a look at https://docs.rs/png/0.16.8/png/#using-the-encoder
I think you're right that something like cropping belongs outside of the psd
crate.
Let me know if you need any more help with this issue, otherwise best of luck.
My goal is to export a layer as a png, excluding any white space.
Oh, and for the excluding any white space portion.
You can handle this with the image crate.
One brute force way:
- Iterate over columns from left to right and find the smallest x coordinate that isn't white.
- Iterate over rows line from top to bottom and find the largest x coordinate that isn't white.
- Same idea for right and bottom
You'll end up with the left, top, right and bottom crop coordinates. Then just call https://docs.rs/image/0.23.13/image/imageops/fn.crop.html
Here's a much simpler way to get an Image
from a psd
.
let img: image::ImageBuffer<image::Rgba<u8>, Vec<u8>> =
image::ImageBuffer::from_vec(psd.width(), psd.height(), psd.pixels()).unwrap();
img.save("/tmp/foo.png").unwrap();