Skip to content

Commit

Permalink
apply gamma correction on grayscale images
Browse files Browse the repository at this point in the history
fixes #38
  • Loading branch information
yagee-de committed Feb 7, 2024
1 parent 9e16c97 commit 8a5491f
Showing 1 changed file with 32 additions and 0 deletions.
32 changes: 32 additions & 0 deletions src/main/java/org/mycore/imagetiler/MCRImage.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,15 @@
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.color.ColorSpace;
import java.awt.color.ICC_ColorSpace;
import java.awt.color.ICC_ProfileGray;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.RescaleOp;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
Expand Down Expand Up @@ -124,6 +128,9 @@ public class MCRImage {
private static final double ZOOM_FACTOR = 0.5;

private static final ColorConvertOp COLOR_CONVERT_OP = new ColorConvertOp(null);
private static final ColorConvertOp SRGB_COLOR_CONVERT_OP
= new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_sRGB), null);
public static final float DEFAULT_GAMMA = 1F;

/**
* derivate ID (for output directory calculation).
Expand Down Expand Up @@ -390,10 +397,35 @@ private static BufferedImage convertIfNeeded(BufferedImage tile) {
}
final BufferedImage newTile = new BufferedImage(tile.getWidth(), tile.getHeight(),
convertToGray ? BufferedImage.TYPE_BYTE_GRAY : BufferedImage.TYPE_INT_RGB);
if (colorModel.getNumColorComponents() == 1) {
//convert to sRGB first and than to grayscale to handle gamma correction
BufferedImage midStep = new BufferedImage(tile.getWidth(), tile.getHeight(), BufferedImage.TYPE_INT_RGB);
SRGB_COLOR_CONVERT_OP.filter(tile, midStep);
float gamma = getGamma(tile.getColorModel().getColorSpace());
if (gamma != DEFAULT_GAMMA) {
gammaCorrection(gamma, midStep, newTile);
return newTile;
}
}
COLOR_CONVERT_OP.filter(tile, newTile);
return newTile;
}

private static float getGamma(ColorSpace colorSpace) {
if (colorSpace instanceof ICC_ColorSpace iccColorSpace
&& iccColorSpace.getProfile() instanceof ICC_ProfileGray grayProfile) {
return grayProfile.getGamma();
}
return DEFAULT_GAMMA;
}

private static void gammaCorrection(float gamma, BufferedImage source, BufferedImage target) {
LOGGER.info("Correcting gamma {}.", gamma);
float gammaCorrectionFactor = (float) Math.pow(1 / gamma, -1);
RescaleOp rop = new RescaleOp(gammaCorrectionFactor, 0, null);
rop.filter(source, target);
}

/**
* @return true, if gray scale image uses color map where every entry uses the same value for each color component
*/
Expand Down

0 comments on commit 8a5491f

Please sign in to comment.