Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trim() cuts portions of the actual image #2363

Closed
KrishKayc opened this issue Sep 10, 2020 · 11 comments
Closed

Trim() cuts portions of the actual image #2363

KrishKayc opened this issue Sep 10, 2020 · 11 comments

Comments

@KrishKayc
Copy link

Hi,

We are using the trim() function to get rid of extra white space around the image.

But there is a recent issue we noticed. Trim() removes the portion of the image. Please find the attached screenshots of the actual image and the image after using Trim().

Note that the dot in the end of the first line gets cut. (after answer, see that portion of 'r' in answer along with the ending fullstop gets cut)

tux
tux_edited

The code that I use is as follows.

sharp(buffer).trim()

Have tried giving threshold for trim with values like 1, 5 12 etc but nothing works. Have tried resize but that does not do the trimming .Please suggest if there is anyother work around to this.

@lovell
Copy link
Owner

lovell commented Sep 10, 2020

Trying this sample image with vips at the command line, I see:

$ vips find_trim 92702797-3be4ef00-f36f-11ea-9dd3-faf2d2bb91eb.png --threshold 1
14
12
644
205

Using these values (top, left, width, height) to extract the area, also via the command line:

$ vips extract_area 92702797-3be4ef00-f36f-11ea-9dd3-faf2d2bb91eb.png out.png 14 12 644 205

I see the same slightly-over-trimmed result as reported.

@jcupitt Are you able to help here? Could this be something to do with the median filter involved in find_trim?

@KrishKayc
Copy link
Author

@lovell Is there any workaround available for this? I saw a lot of similar issues with trim() and workarounds for it, I tried those but nothing worked. Like flattening the image, then trimming etc..

@jcupitt
Copy link
Contributor

jcupitt commented Sep 10, 2020

Hello @KrishKayc,

Yes, find_trim was designed for photographic sources, so it includes a median filter. This will remove the single pixel elements in your PNG file. We'd need to add an option (perhaps vector_source, no_fuzz, or no_noise_removal?) for ultra clean vector art like this.

As a workaround, you'd need to make your own find_trim. It's not complex -- just copy paste the existing trimmer and remove the median filter. If you used C++ it'd be very small.

Looking at find_trim again, it could be made quite a bit quicker too. I'll add an enhancement issue to libvips for this.

@jcupitt
Copy link
Contributor

jcupitt commented Sep 10, 2020

I had a thought: you could flatten, monochrome, blur and then threshold the image before calling find_trim. That would make single pixels elements large enough to get past the median filter.

What an ugly hack!

@KrishKayc
Copy link
Author

@jcupitt Thanks for the workaround. Doing a slight blur() and then trimming worked for this particular use case. So it is a less uglier hack :-)

@miltoncandelero
Copy link

Did this get anywhere?
I see this issue marked as completed on libvips libvips/libvips#1811 but I am still getting problems with trim on pixelart :(

Attached input and output
input
input
(it's a tiny green thingy)

output
output
(it's a tiny black spec above this line)

and the code that ran

const sharp = require("sharp");
const fs = require("fs/promises");

async function test() {
	// giving more info about the background doesn't make a difference :(
	// const { info, data } = await sharp("./input.png").trim({ background: { r: 0, g: 0, b: 0, alpha: 0 }, threshold: 1 }).png().toBuffer({ resolveWithObject: true });

	const { info, data } = await sharp("./input.png").trim().png().toBuffer({ resolveWithObject: true });
	console.log(info);
	await fs.writeFile("./output.png", data);
}

test();

console log

{
  format: 'png',
  width: 1,
  height: 1,
  channels: 4,
  premultiplied: false,
  trimOffsetLeft: -9,
  trimOffsetTop: -8,
  size: 89
}

@lovell
Copy link
Owner

lovell commented Feb 6, 2023

The upstream discussion about a future possible enhancement for this is at libvips/libvips#2076

@earthiverse
Copy link

The upstream discussion about a future possible enhancement for this is at libvips/libvips#2076

It looks like the functionality to do this has been added: libvips/libvips#3329
Is it possible to add an option in TrimOptions that enables this mode?

@lovell
Copy link
Owner

lovell commented Feb 28, 2023

This will be dependent on the future libvips 8.15 and we can revisit once available.

@lovell lovell added this to the v0.33.0 milestone Oct 17, 2023
@lovell
Copy link
Owner

lovell commented Nov 4, 2023

Support for the lineArt option added via commit 0bd1715 and will be part of v0.33.0.

Please note this change also mandates that options are passed to trim() as an Object containing the properties you wish to set. Passing a number or string to represent a threshold or colour respectively will no longer be allowed as of v0.33.0

@lovell
Copy link
Owner

lovell commented Nov 29, 2023

v0.33.0 is now available.

@lovell lovell closed this as completed Nov 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants