Page 1 of 1

About gif Diffusion Transparency Dithering

Posted: 2018-06-03T20:17:19-07:00
by beginner
1.png
Image

convert 1.png -channel RGBA -separate ( +clone -remap pattern:gray50 ) +swap -combine 1.gif

1.gif
Image

If MagickWand APIs is used, what relevant APIs need to be used to implement this function?
please help me.
thanks.

Re: About gif Diffusion Transparency Dithering

Posted: 2018-06-04T05:28:43-07:00
by snibgo
What have you got so far? Which part of the command is causing you difficulty?

Re: About gif Diffusion Transparency Dithering

Posted: 2018-06-04T06:57:26-07:00
by beginner
I use imagemagick 6.8.9

Below is the code I wrote, but the effect of the generated gif image is not what I expected.

I think it must be wrong to use some APIs.

3.gif:
Image

Code: Select all

MagickWand *mw_rgba = NewMagickWand();
MagickReadImage(mw_rgba, "E:\\temp\\1.png");


MagickWand *mw_red = CloneMagickWand(mw_rgba);
MagickWand *mw_green = CloneMagickWand(mw_rgba);
MagickWand *mw_blue = CloneMagickWand(mw_rgba);
MagickWand *mw_alpha = CloneMagickWand(mw_rgba);

//  -channel RGBA -separate ?
MagickSeparateImageChannel(mw_red, RedChannel);
MagickSeparateImageChannel(mw_green, GreenChannel);
MagickSeparateImageChannel(mw_blue, BlueChannel);
MagickSeparateImageChannel(mw_alpha, AlphaChannel);



// ( +clone -remap pattern:gray50 )

MagickWand *mw_clone = CloneMagickWand(mw_alpha); // +clone ?

MagickRemapImage(mw_clone, mw_rgba, FloydSteinbergDitherMethod); // -remap ?

MagickThresholdImage(mw_clone, QuantumRange * 50.0 / 100); // pattern:gray50 ?


// +swap -combine ?
MagickSetImageAlphaChannel(mw_clone, ActivateAlphaChannel);
//MagickSetImageAlphaChannel(mw_alpha, ActivateAlphaChannel);

MagickCompositeImage(mw_red, mw_green, CopyGreenCompositeOp, 0, 0);
MagickCompositeImage(mw_red, mw_blue, CopyBlueCompositeOp, 0, 0);
MagickCompositeImage(mw_red, mw_clone, CopyOpacityCompositeOp, 0, 0);
//MagickCompositeImage(mw_red, mw_alpha, CopyOpacityCompositeOp, 0, 0);


MagickAutoLevelImage(mw_red);


MagickWriteImage(mw_red, "E:\\temp\\3.gif");

What I need is this effect:
Image

Re: About gif Diffusion Transparency Dithering

Posted: 2018-06-04T07:16:47-07:00
by snibgo
Your command uses an image "pattern:gray50" but your wand code doesn't create that image.

Your command remaps using colours from the created image "pattern:gray50", but your wand code remaps using colours from the same image, so this has no effect.

Your wand code has a threshold that isn't in your command.

Re: About gif Diffusion Transparency Dithering

Posted: 2018-06-04T16:18:33-07:00
by beginner
thank you for your reply.

According to your tips, I modified the relevant code:

Code: Select all

MagickWand *mw_rgba = NewMagickWand();
MagickReadImage(mw_rgba, "E:\\temp\\1.png");

MagickWand *mw_red = CloneMagickWand(mw_rgba);
MagickWand *mw_green = CloneMagickWand(mw_rgba);
MagickWand *mw_blue = CloneMagickWand(mw_rgba);
MagickWand *mw_alpha = CloneMagickWand(mw_rgba);

//  -channel RGBA -separate ?
MagickSeparateImageChannel(mw_red, RedChannel);
MagickSeparateImageChannel(mw_green, GreenChannel);
MagickSeparateImageChannel(mw_blue, BlueChannel);
MagickSeparateImageChannel(mw_alpha, AlphaChannel);

// ( +clone -remap pattern:gray50 )
MagickWand *mw_clone = CloneMagickWand(mw_alpha); // +clone ?

MagickWand *mw_gray50 = CloneMagickWand(mw_rgba);
MagickThresholdImage(mw_gray50, QuantumRange * 50.0 / 100); // pattern:gray50 ?

MagickRemapImage(mw_clone, mw_gray50, FloydSteinbergDitherMethod); // -remap ?

// +swap -combine ?
MagickSetImageAlphaChannel(mw_clone, ActivateAlphaChannel);

MagickCompositeImage(mw_red, mw_green, CopyGreenCompositeOp, 0, 0);
MagickCompositeImage(mw_red, mw_blue, CopyBlueCompositeOp, 0, 0);
MagickCompositeImage(mw_red, mw_clone, CopyOpacityCompositeOp, 0, 0);

MagickAutoLevelImage(mw_red);

MagickWriteImage(mw_red, "E:\\temp\\3.gif");
3.gif
Image

The effect is close to expectations, but there are still differences.

Where do I need to improve the code to fully achieve the desired effect ?

---------------------------------------------------------------------------------------------------------------------

convert 1.png -channel RGBA -separate ( +clone -remap pattern:gray50 ) +swap -combine 1.gif

1.gif
Image

Re: About gif Diffusion Transparency Dithering

Posted: 2018-06-04T17:01:54-07:00
by fmw42
Try changing the -dither before -remap. See http://www.imagemagick.org/Usage/quantize/#remap

Re: About gif Diffusion Transparency Dithering

Posted: 2018-06-04T19:03:52-07:00
by snibgo
The default dither method is "Riemersma", not Floyd-Steinberg.

Re: About gif Diffusion Transparency Dithering

Posted: 2018-06-05T05:12:20-07:00
by beginner
Thank you for your help!

I tried two different methods:

Code: Select all

MagickWand *mw_clone = CloneMagickWand(mw_alpha); // +clone

MagickWand *mw_gray50 = CloneMagickWand(mw_rgba);

MagickThresholdImage(mw_gray50, QuantumRange * 95.0 / 100);

MagickRemapImage(mw_clone, mw_gray50, RiemersmaDitherMethod); // -remap
Image

------------------------------------------------------------------------------------------------------------------

Code: Select all

MagickWand *mw_clone = CloneMagickWand(mw_alpha); // +clone

MagickWand *mw_gray50 = CloneMagickWand(mw_rgba);

MagickThresholdImageChannel(mw_gray50, AlphaChannel, QuantumRange * 50.0 / 100);
MagickOrderedPosterizeImage(mw_gray50, "o8x8,4");

MagickRemapImage(mw_clone, mw_gray50, RiemersmaDitherMethod); // -remap
Image

------------------------------------------------------------------------------------------------------------------

The effect of these two methods is very close to expectations, but there are still differences.

Re: About gif Diffusion Transparency Dithering

Posted: 2018-06-05T05:32:28-07:00
by snibgo
As I have already said, you are not using the same image for remap.

Do you still have auto-level in your wand code but not the CLI version? That won't help.

You can compare the versions by writing intermediate results to disk.

Re: About gif Diffusion Transparency Dithering

Posted: 2018-06-05T16:47:33-07:00
by beginner
I tried another simple method

Code: Select all

MagickWand *mw_rgba = NewMagickWand();
MagickReadImage(mw_rgba, "E:\\temp\\1.png");

MagickWand *mw_clone = CloneMagickWand(mw_rgba); // +clone ?

MagickWand *mw_gray50 = CloneMagickWand(mw_rgba);

MagickThresholdImageChannel(mw_gray50, AlphaChannel, QuantumRange * 50.0 / 100); // pattern:gray50 ?
MagickOrderedPosterizeImage(mw_gray50, "o8x8,4"); //(50 grey)

MagickRemapImage(mw_clone, mw_gray50, RiemersmaDitherMethod); // -remap ?

MagickSetImageAlphaChannel(mw_clone, ActivateAlphaChannel);
MagickCompositeImage(mw_rgba, mw_clone, CopyOpacityCompositeOp, 0, 0);  // +swap -combine ?

MagickAutoLevelImage(mw_rgba);

MagickWriteImage(mw_rgba, "E:\\temp\\2.gif");
Image

Closer to expected effect.