@Property(category = PropertyCategory.PRIMARY, description = "Foreground intensity")
private double intensity = 1.0;
@Override
protected void performImageTransformation(WFImage pImg) {
SimpleHDRImage fgImg = foreground.getHDRImage();
SimpleHDRImage bgImg = (SimpleHDRImage) pImg;
if ((fgImg.getImageWidth() != bgImg.getImageWidth()) || (fgImg.getImageHeight() != bgImg.getImageHeight())) {
throw new IllegalArgumentException();
}
SimpleHDRImage res = new SimpleHDRImage(fgImg.getImageWidth(), fgImg.getImageHeight());
float fgRGB[] = new float[3];
float bgRGB[] = new float[3];
float r, g, b;
float trans = (float) transparency * 0.01f;
if (trans < 0.0f) {
trans = 0.0f;
}
else if (trans > 1.0f) {
trans = 1.0f;
}
float invTrans = 1.0f - trans;
float fgScale = (float) intensity;
float bgScale = (float) intensity;
float fgRed, fgGreen, fgBlue;
float bgRed, bgGreen, bgBlue;
float mergedRed, mergedGreen, mergedBlue;
HSLTransformer fgHSL = new HSLTransformer();
HSLTransformer bgHSL = new HSLTransformer();
HSLTransformer mergedHSL = new HSLTransformer();
float lum[] = new float[2];
fgImg.getMinMaxLum(lum);
float fgLumMin = lum[0];
float fgLumMax = lum[1];
if ((fgLumMax - fgLumMin) < MathLib.EPSILON) {
fgLumMax = fgLumMin + (float) MathLib.EPSILON;
}
bgImg.getMinMaxLum(lum);
float bgLumMin = lum[0];
float bgLumMax = lum[1];
if ((bgLumMax - bgLumMin) < MathLib.EPSILON) {
bgLumMax = bgLumMin + (float) MathLib.EPSILON;
}
bgScale *= (fgLumMax - fgLumMin) / (bgLumMax - bgLumMin);
for (int i = 0; i < fgImg.getImageHeight(); i++) {
for (int j = 0; j < fgImg.getImageWidth(); j++) {
fgImg.getRGBValues(fgRGB, j, i);
fgRed = fgRGB[0] * fgScale;
fgGreen = fgRGB[1] * fgScale;
fgBlue = fgRGB[2] * fgScale;
bgRed = bgRGB[0] * bgScale;
bgGreen = bgRGB[1] * bgScale;
bgBlue = bgRGB[2] * bgScale;
bgImg.getRGBValues(bgRGB, j, i);
switch (mergeMode) {
case MULTIPLY:
mergedRed = fgRed * bgRed;
mergedGreen = fgGreen * bgGreen;
mergedBlue = fgBlue * bgBlue;
break;
case ADD:
mergedRed = (fgRed + bgRed) * 0.5f;
mergedGreen = (fgGreen + bgGreen) * 0.5f;
mergedBlue = (fgBlue + bgBlue) * 0.5f;
break;
case SUBTRACT:
mergedRed = bgRed - fgRed;
if (mergedRed < 0.0f) {
mergedRed = 0.0f;
}
mergedGreen = bgGreen - fgGreen;
if (mergedGreen < 0.0f) {
mergedGreen = 0.0f;
}
mergedBlue = bgBlue - fgBlue;
if (mergedBlue < 0.0f) {
mergedBlue = 0.0f;
}
break;
case RED:
mergedRed = fgRed;
mergedGreen = bgGreen;
mergedBlue = bgBlue;
break;
case GREEN:
mergedRed = bgRed;
mergedGreen = fgGreen;
mergedBlue = bgBlue;
break;
case BLUE:
mergedRed = bgRed;
mergedGreen = bgGreen;
mergedBlue = fgBlue;
break;
case LIGHTEN: {
float fgLum = SimpleHDRImage.calcLum(fgRed, fgGreen, fgBlue);
float bgLum = SimpleHDRImage.calcLum(bgRed, bgGreen, bgBlue);
if (fgLum > bgLum) {
mergedRed = fgRed;
mergedGreen = fgGreen;
mergedBlue = fgBlue;
}
else {
mergedRed = bgRed;
mergedGreen = bgGreen;
mergedBlue = bgBlue;
}
}
break;
case DARKEN: {
float fgLum = SimpleHDRImage.calcLum(fgRed, fgGreen, fgBlue);
float bgLum = SimpleHDRImage.calcLum(bgRed, bgGreen, bgBlue);
if (fgLum < bgLum) {
mergedRed = fgRed;
mergedGreen = fgGreen;
mergedBlue = fgBlue;
}
else {
mergedRed = bgRed;
mergedGreen = bgGreen;
mergedBlue = bgBlue;
}
}
break;
case HSL_ADD:
fgHSL.setRGB(fgRed, fgGreen, fgBlue);
bgHSL.setRGB(bgRed, bgGreen, bgBlue);
mergedHSL.setHSL(fgHSL.getHue() + bgHSL.getHue(), fgHSL.getSaturation() + bgHSL.getSaturation(), fgHSL.getLuminosity() + bgHSL.getLuminosity(), fgHSL.getAmp());
mergedRed = mergedHSL.getRed();
mergedGreen = mergedHSL.getGreen();
mergedBlue = mergedHSL.getBlue();
break;
default:
mergedRed = fgRed;
mergedGreen = fgGreen;
mergedBlue = fgBlue;
break;
}
r = mergedRed * invTrans + bgRed * trans;
g = mergedGreen * invTrans + bgGreen * trans;
b = mergedBlue * invTrans + bgBlue * trans;
res.setRGB(j, i, r, g, b);
}
}
((SimpleHDRImage) pImg).assignImage(res);
}