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

Image mode reset at the end of process method #34

Open
fabiocaccamo opened this issue Jan 10, 2019 · 4 comments
Open

Image mode reset at the end of process method #34

fabiocaccamo opened this issue Jan 10, 2019 · 4 comments

Comments

@fabiocaccamo
Copy link

fabiocaccamo commented Jan 10, 2019

Thank you for this great library.

I'm trying to convert a jpg image to black and white and store it in its original format, but I got the following error:
IOError at ... cannot write mode RGBA as JPEG

The cause is that some processors need to change image mode to perform operations, but doesn't reset it to its init value at the end of the process.

I ended up writing my own filter to preserve image mode:

from pilkit.processors import Adjust


class BlackAndWhite(object):

    def __init__(self):
        self.processor = Adjust(color=0.0)

    def process(self, img):
        img_mode = img.mode
        img = self.processor.process(img)
        img = img.convert(img_mode)
        return img
@kravemir
Copy link
Contributor

kravemir commented Mar 3, 2019

There was recently merged Convert processor in #32, which you can add to the end of a ProcessorPipeline, and convert image back to RGB mode.

@fabiocaccamo
Copy link
Author

@kravemir Convert processor doesn't convert the image to its original format, the conversion should be handled internally and not by a processor.

Using a processor you will convert all images to the same format, the need is to convert each image to its original format after processing it.

@kravemir
Copy link
Contributor

kravemir commented Mar 3, 2019

@kravemir Convert processor doesn't convert the image to its original format, ...

@fabiocaccamo I now get the difference. Sorry for the wrong suggestion.

So, you would need something like PreserveMode processor, or ConvertBackToOriginalMode processor, which wraps other processor (or, array of processors). Like, you have shown in yours example.

... the conversion should be handled internally and not by a processor.

What do you mean by "handled internally"? A processor, or a composition of processor using ProcessorPipeline, is called by process method to transform original image into a new image. And, a processor might return a different image object, than is the original one, as it depends on transformation, which is performed. So, in the end, the execution needs to be wrapped within some method, or processor.

@fabiocaccamo
Copy link
Author

@kravemir exactly, this is how I actually solved the problem, here a custom processor example:

class BlackAndWhite(object):

    def __init__(self):
        self.processor = Adjust(color=0.0)

    def process(self, img):
        img_mode = img.mode
        img = self.processor.process(img)
        img = img.convert(img_mode)
        return img

I think that img_mode = img.mode and img = img.convert(img_mode) lines should be handled by the library to avoid duplicated code that solves always the same problem.

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

No branches or pull requests

2 participants