1 /* Copyright (C) 2005-2011 Fabio Riccardi */ 2 3 package com.lightcrafts.jai.opimage; 4 5 import com.lightcrafts.mediax.jai.PointOpImage; 6 import com.lightcrafts.mediax.jai.ImageLayout; 7 import com.lightcrafts.mediax.jai.RasterAccessor; 8 import com.lightcrafts.mediax.jai.RasterFormatTag; 9 10 import java.awt.image.*; 11 import java.awt.color.ColorSpace; 12 import java.awt.*; 13 import java.util.Map; 14 15 /** 16 * Created by IntelliJ IDEA. 17 * User: fabio 18 * Date: Mar 13, 2007 19 * Time: 2:36:29 PM 20 * To change this template use File | Settings | File Templates. 21 */ 22 public class RedMaskOpImage extends PointOpImage { 23 private final double tolerance; 24 createLayout(RenderedImage source)25 private static ImageLayout createLayout(RenderedImage source) { 26 ColorModel cm = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY), 27 false, false, 28 Transparency.OPAQUE, DataBuffer.TYPE_BYTE); 29 30 ImageLayout layout = new ImageLayout(source); 31 layout.setColorModel(cm); 32 layout.setSampleModel(cm.createCompatibleSampleModel(source.getWidth(), source.getHeight())); 33 return layout; 34 } 35 RedMaskOpImage(RenderedImage source, double tolerance, Map config)36 public RedMaskOpImage(RenderedImage source, double tolerance, Map config) { 37 super(source, createLayout(source), config, true); 38 this.tolerance = tolerance; 39 } 40 41 @Override computeRect(Raster[] sources, WritableRaster dest, Rectangle destRect)42 protected void computeRect(Raster[] sources, 43 WritableRaster dest, 44 Rectangle destRect) { 45 // Retrieve format tags. 46 RasterFormatTag[] formatTags = getFormatTags(); 47 48 Raster source = sources[0]; 49 Rectangle srcRect = mapDestRect(destRect, 0); 50 51 RasterAccessor src = new RasterAccessor(source, srcRect, formatTags[0], 52 getSourceImage(0).getColorModel()); 53 RasterAccessor dst = new RasterAccessor(dest, destRect, formatTags[1], getColorModel()); 54 55 switch (dst.getDataType()) { 56 case DataBuffer.TYPE_BYTE: 57 ushortLoop(src, dst); 58 break; 59 default: 60 throw new UnsupportedOperationException("Unsupported data type: " + dst.getDataType()); 61 } 62 } 63 ushortLoop(RasterAccessor src, RasterAccessor dst)64 protected void ushortLoop(RasterAccessor src, RasterAccessor dst) { 65 int width = src.getWidth(); 66 int height = src.getHeight(); 67 68 byte dstData[] = dst.getByteDataArray(0); 69 int dstBandOffsets[] = dst.getBandOffsets(); 70 int dstLineStride = dst.getScanlineStride(); 71 int dstPixelStride = dst.getPixelStride(); 72 73 short srcData[] = src.getShortDataArray(0); 74 int srcBandOffsets[] = src.getBandOffsets(); 75 int srcLineStride = src.getScanlineStride(); 76 int srcPixelStride = src.getPixelStride(); 77 78 int srcLOffset = srcBandOffsets[0]; 79 int srcAOffset = srcBandOffsets[1]; 80 int srcBOffset = srcBandOffsets[2]; 81 82 int dstOffset = dstBandOffsets[0]; 83 84 // double ra = 68; double radev = 15.3 * tolerance; 85 // double rb = 39; double rbdev = 14.5 * tolerance; 86 // 87 // int raMin = (int) ((ra - radev) * 256); 88 // int raMax = (int) ((ra + radev) * 256); 89 // int rbMin = (int) ((rb - rbdev) * 256); 90 // int rbMax = (int) ((rb + rbdev) * 256); 91 // 92 // double sa = 19; double sadev = 5.1 * 3.5; 93 // double sb = 17; double sbdev = 2.66 * 3.5; 94 // 95 // int saMin = (int) ((sa - sadev) * 256); 96 // int saMax = (int) ((sa + sadev) * 256); 97 // int sbMin = (int) ((sb - sbdev) * 256); 98 // int sbMax = (int) ((sb + sbdev) * 256); 99 100 // Sclera Red 101 int raMin = (int) ((71.5 - 48.5 * tolerance) * 256); 102 int raMax = (int) ((71.5 + 48.5 * tolerance) * 256); 103 int rbMin = (int) ((8 - 35 * tolerance) * 256); 104 int rbMax = (int) ((8 + 35 * tolerance) * 256); 105 106 // Really Red 107 int rraMin = (int) ((62 - 6.8 * 2) * 256); 108 int rraMax = (int) ((62 + 6.8 * 2) * 256); 109 int rrbMin = (int) ((35 - 6.5 * 2) * 256); 110 int rrbMax = (int) ((35 + 6.5 * 2) * 256); 111 112 // Kinda Orange 113 int oaMin = (31 - 15 * 2) * 256; 114 int oaMax = (31 + 15 * 2) * 256; 115 int obMin = (56 - 5 * 2) * 256; 116 int obMax = (56 + 5 * 2) * 256; 117 118 // Magenta 119 // int maMin = ( 30 - 12 * 2) * 256; 120 // int maMax = ( 30 + 12 * 2) * 256; 121 // int mbMin = (-12 - 13 * 2) * 256; 122 // int mbMax = (-12 + 13 * 2) * 256; 123 124 // Skin 125 int sLMin = (int) (43.3593 * 0xffff / 100); 126 int sLMax = (int) (99.6093 * 0xffff / 100); 127 int saMin = (int) (1.5 * 256); 128 int saMax = (int) (43.125 * 256); 129 int sbMin = (int) (-4.6875 * 256); 130 int sbMax = (int) (34.6875 * 256); 131 132 for (int row = 0; row < height; row++) { 133 for (int col = 0; col < width; col++) { 134 int L = 0xffff & srcData[3 * col + row * srcLineStride + srcLOffset]; 135 int a = 0xffff & srcData[srcPixelStride * col + row * srcLineStride + srcAOffset] - 128 * 256; 136 int b = 0xffff & srcData[srcPixelStride * col + row * srcLineStride + srcBOffset] - 128 * 256; 137 138 if (((a > raMin && a < raMax && b > rbMin && b < rbMax) 139 || (a > oaMin && a < oaMax && b > obMin && b < obMax) 140 || (a > rraMin && a < rraMax && b > rrbMin && b < rrbMax)) 141 // || (a > maMin && a < maMax && b > mbMin && b < mbMax)) 142 && !(L > sLMin && L < sLMax && a > saMin && a < saMax && b > sbMin && b < sbMax)) 143 dstData[dstPixelStride * col + row * dstLineStride + dstOffset] = (byte) 0xff; 144 else 145 dstData[dstPixelStride * col + row * dstLineStride + dstOffset] = (byte) 0; 146 } 147 } 148 } 149 } 150