Example #1
0
  void AdjustLuminance::onInput(InputImageInfo info, Magick::Image img) {
    std::vector<std::pair < Magick::Color, size_t>> histogram;
    Magick::colorHistogram(&histogram, img);
    Magick::Image original = img;
    /* gamma correction rules:
     * http://www.imagemagick.org/Usage/transform/#evaluate_pow
     * 
     *  updatedColor = color ^ (1 / gamma)
     *  gamma = 1 / log(color, updatedColor)
     *  gamma = 1 / (log(updatedColor) / log(color))
     * 
     * We can't compute gamma just from current and target luminance, 
     * but we can estimate it. 
     * 
     * We can compute expected luminance after gamma 
     * correction from image histogram, it is relatively fast. 
     * So we iterate gamma estimation ten times. Results are relatively good.
     */
    double gamma = 1.0;
    double targetLuminance = info.luminanceChange + info.luminance;
    double expectedLuminance = info.luminance;

    for (int iteration = 0; iteration < 10; iteration++) {

      gamma *= 1 / (
        std::log(Magick::Color::scaleQuantumToDouble(targetLuminance)) /
        std::log(Magick::Color::scaleQuantumToDouble(expectedLuminance)));

      expectedLuminance = ComputeLuminance::computeLuminance(histogram, gamma);

      *verboseOutput << QString("%1 iteration %2 changing gamma to %3 (expected luminance: %4, target %5, abs(diff) %6)")
        .arg(info.file.filePath())
        .arg(iteration)
        .arg(gamma)
        .arg(expectedLuminance)
        .arg(targetLuminance)
        .arg(std::abs(expectedLuminance - targetLuminance))
        << endl;
    }

    img.gamma(gamma);
    if (debugView) {
      original.transform(
        Magick::Geometry(original.columns(), original.rows()),
        Magick::Geometry(original.columns() / 2, original.rows())
        );
      img.composite(original, 0, 0, Magick::DissolveCompositeOp);
    }
    //img.brightnessContrast(brighnessChange, /* contrast */0.0);
    emit input(info, img);
  }
Example #2
0
void Magick::gammaImage::operator()( Magick::Image &image_ ) const
{
  image_.gamma( _gammaRed, _gammaGreen, _gammaBlue );
}