Page 1 of 1

Linear Stretch with Magick++

Posted: 2011-03-22T14:51:44-07:00
by cappelaere
With the Magick++ API, how can I do a 5% linear stretch...something equivalent to:
>convert test.png -linear-stretch 5x5% level.png
[interestingly convert test.png -linear-stretch 5x95% level.png did not work]

I tried to use "level" but it did not seem to produce the expected results
my example:
double stretch = 5.0;
double black = stretch*MaxRGB/100.0;
double white = (100.0-stretch)*MaxRGB/100.0;
img->level(black, white);

Many thanks,
Pat.

Re: Linear Stretch with Magick++

Posted: 2011-03-22T15:32:10-07:00
by fmw42
linear-stretch and contrast-stretch work by counting pixels from the ends of the histogram to get the graylevels to stretch. level works by stretch from exact graylevels

it appears that the old difference between linear-stretch black-point/white-point being complements has been fixed so that linear-stretch and contrast-stretch work the same. the percent values are from the corresponding ends. -contrast-stretch is sensitive to -channel, but -linear-stretch is not (unless Anthony has fixed that also).

The main difference is that -constrast-stretch 0 is similar to -auto-level in that it finds the first non-empty bin from the ends of the histogram to start counting. -linear-stretch 0 will make no change as it starts counting from the ends of the histogram even if empty.

Sorry I don't know the APIs well enough to tell you the equivalent commands.

It looks like neither is included in http://www.imagemagick.org/Magick++/Image.html. Though the docs may just be outdated.

However, normalize is equivalent to -contrast-stretch 2%x1%

Re: Linear Stretch with Magick++

Posted: 2011-03-22T19:22:27-07:00
by cappelaere
I tried to use the MagicCore C Api with Magick++ API but it is not working too well.
I am getting error: 'ContrastStretchImage' was not declared in this scope!
Not sure if you can mix the two APIs or if anyone tried to do this before.
Any help would be appreciated.
Thanks,
Pat.

Re: Linear Stretch with Magick++

Posted: 2011-03-23T05:17:14-07:00
by magick
The Magick++ and MagickCore API's are designed to interact with each others. Instead of ContastStretchImage(), put it in the proper namespace with MagickCore::ContrastStretchImage().

Re: Linear Stretch with Magick++

Posted: 2011-03-23T06:32:57-07:00
by cappelaere
Ok did that.
But now, how would you convert a Magick::Image* to a MagickCore::Image* ?
A straight cast does not seem to be enough.
Assertion failed: (image->signature == MagickSignature), function ContrastStretchImageChannel
Thanks again.
Pat.

Re: Linear Stretch with Magick++

Posted: 2011-03-23T06:47:42-07:00
by cappelaere
Figured it out:
MagickCore::Image* img_core = img->image();

Works great.
Thanks.
Pat.

Re: Linear Stretch with Magick++

Posted: 2011-05-13T23:44:24-07:00
by cocheese
I am trying to do something very similar as well.

Would someone mind posting an example of the proper interaction between the Magick++ and MagickCore functions?


EDIT: I have it working for MinifyImage, which returns a MagickCore Image*, but ContrastStretchImageChannel returns MagickBooleanType... I am not really sure how to get the resulting image.

Code: Select all

// ...
// Instantiate Magick::Image m_i from a buffer
// ...

MagickCore::Image* mc_i = i.image(); // Magick++ --> MagickCore
MagickCoreExceptionInfo* e = MagickCore::AcquireExceptionInfo();
MagickCore::Image* new_mc_i = MagickCore::MinifyImage(mc_i, e); // simple MagickCore function call
MagickCore::CatchException(e);
MagickCore::ImageInfo* mc_ii = MagickCore::AcquireImageInfo();

size_t l;
unsigned char* buffer = MagickCore::ImageToBlob(mc_ii, mc_i, &new_size, e);
MagickCore::CatchException(e);

//MagickCore back to Magick++
Magick::Blob m_b(buffer, l);
Magick::Image m_i2(m_b);

//Continue in Magick namespace
// ...

mc_ii = MagickCore::DestroyImageInfo(mc_ii);
mc_i = MagickCore::DestroyImage(mc_i);
e = MagickCore::DestroyExceptionInfo(e);

// ...

Again, not really sure how to do something similar for ContrastStretchImageChannel... Where can I grab a pointer to the image since it's not being returned?