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

Help converting raw input with color-profile to srgb #4195

Open
labsforge opened this issue Aug 22, 2024 · 2 comments
Open

Help converting raw input with color-profile to srgb #4195

labsforge opened this issue Aug 22, 2024 · 2 comments
Labels

Comments

@labsforge
Copy link

Hi @lovell, I've tryed to all means to get this output image to work, but its getting out of my knowledge to fix it.
The goal is to import a psd layer0 pixel data as a raw input to sharp. Everything works fine if the psd is sRGB, but I have here an Adobe RGB psd file, that I can't get it right, the image gets desaturated.
I've tryed to export the image from photoshop with Adobe RGB icc embeded, and the jpg colors imports good, the issue is how to initialize the raw with the icc profile.
One of the problems, is that psd files uses xmp metadata, and I can use the "withMetadata" because I'm creating a raw, so I created a simple xmpParser to check for the color-profile tag.
I'm using ag-psd to read the psd and access the layer0 pixel-data buffer.

"sharp": "0.31.1",
"ag-psd": "20.2.0"
const psdBuffer = fs.readFileSync(photo.localPath);
const psd = readPsd(psdBuffer, { useImageData: true, skipThumbnail: false });
const imageDataBuffer = psd.bitsPerChannel === 16 ? Buffer.from(psd.imageData.data) : psd.imageData.data;

let sharpInstance = sharp(imageDataBuffer, {
  raw: {
    width: psd.imageData.width,
    height: psd.imageData.height,
    channels: 4
  }
});

// Extract XMP metadata
const xmpMetadata = psd.imageResources?.xmpMetadata ? psd.imageResources.xmpMetadata.toString() : null;
if (xmpMetadata) {
  return from(this.extractIccFromPsdXmp(xmpMetadata)).pipe(
    switchMap(iccProfilePath => {
      if (iccProfilePath) {
        return of(sharpInstance.withMetadata({
          icc: iccProfilePath,
        }));
      }
      return of(sharpInstance);
    }),
    catchError(err => of(sharpInstance)),
  );
}        

return of(sharpInstance);
}

I've also tried to add "toColorspace('srgb')" and the result is the same.

Files: https://www.pipebytes.com/zQnyxcio

Am I missing something?
Thank you, Rui

@labsforge
Copy link
Author

I can say that with ".pipelineColorspace('rbg16')" it helps a lot, but not as good as the direct jpg convertion.

@lovell
Copy link
Owner

lovell commented Aug 25, 2024

with ".pipelineColorspace('rbg16')" it helps a lot

Yes, this is a suitable approach when imageDataBuffer is raw Uint16Array (maybe this should be the default?).

"sharp": "0.31.1",

Please upgrade to the latest version for various bug fixes and improvements relating to ICC profiles, including more fine-grained control over output metadata such as withIccProfile.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants