/******************************************************************************* * Copyright (c) 2016 Weasis Team and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nicolas Roduit - initial API and implementation *******************************************************************************/ package org.weasis.core.api.image; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.RenderingHints; import java.awt.geom.Area; import java.awt.image.DataBuffer; import java.awt.image.MultiPixelPackedSampleModel; import java.awt.image.RenderedImage; import java.awt.image.SampleModel; import javax.media.jai.ImageLayout; import javax.media.jai.JAI; import javax.media.jai.PlanarImage; import javax.media.jai.ROIShape; import javax.media.jai.TiledImage; import javax.media.jai.operator.ConstantDescriptor; import org.weasis.core.api.image.op.ShutterDescriptor; public class MaskOp extends AbstractOp { public static final String OP_NAME = "Mask"; //$NON-NLS-1$ /** * Set whether the shutter is applied (Required parameter). * * Boolean value. */ public static final String P_SHOW = "show"; //$NON-NLS-1$ public static final String P_SHAPE = "shape"; //$NON-NLS-1$ public static final String P_RGB_COLOR = "rgb.color"; //$NON-NLS-1$ public static final String P_GRAY_TRANSPARENCY = "img.transparency"; //$NON-NLS-1$ public MaskOp() { setName(OP_NAME); } public MaskOp(MaskOp op) { super(op); } @Override public MaskOp copy() { return new MaskOp(this); } @Override public void process() throws Exception { RenderedImage source = (RenderedImage) params.get(Param.INPUT_IMG); RenderedImage result = source; Boolean mask = (Boolean) params.get(P_SHOW); Area area = (Area) params.get(P_SHAPE); if (mask != null && mask && area != null && !area.equals(new Area(new Rectangle(0, 0, source.getWidth(), source.getHeight())))) { Integer transparency = (Integer) params.get(P_GRAY_TRANSPARENCY); Byte[] color = getMaskColor(); if (transparency == null && isBlack(color)) { result = ShutterDescriptor.create(source, new ROIShape(area), getMaskColor(), null); } else { RenderedImage sourceUP; if (transparency != null) { sourceUP = MergeImgOp.combineTwoImages(source, getEmptyImage(getByteValues(Color.GRAY), source), transparency); } else { sourceUP = getEmptyImage(color, source); } result = MergeImgOp.combineTwoImages(source, sourceUP, getAsImage(area, source)); } } params.put(Param.OUTPUT_IMG, result); } private static Byte[] getByteValues(Color color) { return new Byte[] { (byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue() }; } private static PlanarImage getEmptyImage(Byte[] bandValues, RenderedImage source) { RenderingHints hints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, new ImageLayout(source)); return ConstantDescriptor.create((float) source.getWidth() , (float) source.getHeight(), bandValues, hints); } private boolean isBlack(Byte[] color) { for (Byte i : color) { if (i != 0) { return false; } } return true; } private Byte[] getMaskColor() { Color color = (Color) params.get(P_RGB_COLOR); if (color == null) { return new Byte[] { 0 }; } else { return new Byte[] { (byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue() }; } } private PlanarImage getAsImage(Area shape, RenderedImage source) { SampleModel sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, source.getWidth(), source.getHeight(), 1); TiledImage ti = new TiledImage(source.getMinX(), source.getMinY(), source.getWidth(), source.getHeight(), source.getTileGridXOffset(), source.getTileGridYOffset(), sm, PlanarImage.createColorModel(sm)); Graphics2D g2d = ti.createGraphics(); // Write the Shape into the TiledImageGraphics. g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.fill(shape); g2d.dispose(); return ti; } }