Linear Stretch with Magick++

Magick++ is an object-oriented C++ interface to ImageMagick. Use this forum to discuss, make suggestions about, or report bugs concerning Magick++.
Post Reply
cappelaere
Posts: 6
Joined: 2011-02-16T11:11:40-07:00
Authentication code: 8675308

Linear Stretch with Magick++

Post by cappelaere » 2011-03-22T14:51:44-07:00

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.

User avatar
fmw42
Posts: 25131
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Linear Stretch with Magick++

Post by fmw42 » 2011-03-22T15:32:10-07:00

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%

cappelaere
Posts: 6
Joined: 2011-02-16T11:11:40-07:00
Authentication code: 8675308

Re: Linear Stretch with Magick++

Post by cappelaere » 2011-03-22T19:22:27-07:00

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.

User avatar
magick
Site Admin
Posts: 10995
Joined: 2003-05-31T11:32:55-07:00

Re: Linear Stretch with Magick++

Post by magick » 2011-03-23T05:17:14-07:00

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().

cappelaere
Posts: 6
Joined: 2011-02-16T11:11:40-07:00
Authentication code: 8675308

Re: Linear Stretch with Magick++

Post by cappelaere » 2011-03-23T06:32:57-07:00

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.

cappelaere
Posts: 6
Joined: 2011-02-16T11:11:40-07:00
Authentication code: 8675308

Re: Linear Stretch with Magick++

Post by cappelaere » 2011-03-23T06:47:42-07:00

Figured it out:
MagickCore::Image* img_core = img->image();

Works great.
Thanks.
Pat.

cocheese
Posts: 1
Joined: 2011-05-13T23:42:52-07:00
Authentication code: 8675308

Re: Linear Stretch with Magick++

Post by cocheese » 2011-05-13T23:44:24-07:00

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?

Post Reply