/**
* Copyright 2010-2013 Jingjing Li.
*
* This file is part of jplot2d.
*
* jplot2d is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or any later version.
*
* jplot2d is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with jplot2d. If not, see .
*/
package org.jplot2d.element.impl;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.geom.Dimension2D;
import java.awt.image.BandedSampleModel;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.Raster;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.util.Map;
import org.jplot2d.data.ImageDataBuffer;
import org.jplot2d.data.MultiBandImageData;
import org.jplot2d.element.RGBImageMapping;
import org.jplot2d.transform.NormalTransform;
import org.jplot2d.transform.PaperTransform;
public class RGBImageGraphImpl extends GraphImpl implements RGBImageGraphEx, IntermediateCacheEx {
private RGBImageMappingEx mapping;
private MultiBandImageData data;
public RGBImageGraphImpl() {
super();
}
public String getId() {
if (getParent() != null) {
return "RGBImageGraph" + getParent().indexOf(this);
} else {
return "RGBImageGraph@" + Integer.toHexString(System.identityHashCode(this));
}
}
public RGBImageMappingEx getMapping() {
return mapping;
}
public void setMapping(RGBImageMapping mapping) {
if (this.mapping != null) {
this.mapping.removeImageGraph(this);
}
this.mapping = (RGBImageMappingEx) mapping;
if (this.mapping != null) {
this.mapping.addImageGraph(this);
}
}
public MultiBandImageData getData() {
return data;
}
public void setData(MultiBandImageData data) {
MultiBandImageData olddata = this.data;
this.data = data;
if (olddata == null || data == null || data.getDataBuffer()[0] != olddata.getDataBuffer()[0]) {
mapping.getRedTransform().recalcLimits();
}
if (olddata == null || data == null || data.getDataBuffer()[1] != olddata.getDataBuffer()[1]) {
mapping.getGreenTransform().recalcLimits();
}
if (olddata == null || data == null || data.getDataBuffer()[2] != olddata.getDataBuffer()[2]) {
mapping.getBlueTransform().recalcLimits();
}
redraw(this);
}
public void thisEffectiveColorChanged() {
// the color for NaN?
}
public void mappingChanged() {
redraw(this);
}
public Object createCacheHolder() {
if (data == null) {
return null;
}
ImageZscaleCache.Key[] cacheHolder = new ImageZscaleCache.Key[3];
ImageBandTransformEx redTrans = mapping.getRedTransform();
ImageBandTransformEx greenTrans = mapping.getGreenTransform();
ImageBandTransformEx blueTrans = mapping.getBlueTransform();
cacheHolder[0] = ImageZscaleCache.createCacheFor(data.getDataBuffer()[0], data.getWidth(), data.getHeight(),
redTrans.getLimits(), redTrans.getIntensityTransform(), redTrans.getBias(), redTrans.getGain(), 8);
cacheHolder[1] = ImageZscaleCache.createCacheFor(data.getDataBuffer()[0], data.getWidth(), data.getHeight(),
greenTrans.getLimits(), greenTrans.getIntensityTransform(), greenTrans.getBias(), greenTrans.getGain(),
8);
cacheHolder[2] = ImageZscaleCache.createCacheFor(data.getDataBuffer()[0], data.getWidth(), data.getHeight(),
blueTrans.getLimits(), blueTrans.getIntensityTransform(), blueTrans.getBias(), blueTrans.getGain(), 8);
return cacheHolder;
}
@Override
public ComponentEx copyStructure(Map orig2copyMap) {
RGBImageGraphImpl result = (RGBImageGraphImpl) super.copyStructure(orig2copyMap);
// copy or link image mapping
RGBImageMappingEx mappingCopy = (RGBImageMappingEx) orig2copyMap.get(mapping);
if (mappingCopy == null) {
mappingCopy = (RGBImageMappingEx) mapping.copyStructure(orig2copyMap);
}
result.mapping = mappingCopy;
mappingCopy.addImageGraph(result);
return result;
}
@Override
public void copyFrom(ElementEx src) {
super.copyFrom(src);
this.data = ((RGBImageGraphImpl) src).data;
}
public void draw(Graphics2D graphics) {
if (data == null) {
return;
}
ImageBandTransformEx redTrans = mapping.getRedTransform();
ImageBandTransformEx greenTrans = mapping.getGreenTransform();
ImageBandTransformEx blueTrans = mapping.getBlueTransform();
double[] redLimits = mapping.getRedTransform().getLimits();
double[] greenLimits = mapping.getGreenTransform().getLimits();
double[] blueLimits = mapping.getBlueTransform().getLimits();
// limits is null means there is no valid data
if (redLimits == null && greenLimits == null && blueLimits == null) {
return;
}
// find a proper region to process
int width = data.getWidth();
int height = data.getHeight();
double xval = data.getXRange().getMin();
double yval = data.getYRange().getMin();
// apply limits to generate a raster
WritableRaster raster = null;
ImageDataBuffer[] idbs = data.getDataBuffer();
int bands = idbs.length;
byte[][] result = new byte[bands][];
result[0] = (byte[]) ImageZscaleCache.getValue(idbs[0], width, height, redLimits,
redTrans.getIntensityTransform(), redTrans.getBias(), redTrans.getGain(), 8);
result[1] = (byte[]) ImageZscaleCache.getValue(idbs[1], width, height, greenLimits,
greenTrans.getIntensityTransform(), greenTrans.getBias(), greenTrans.getGain(), 8);
result[2] = (byte[]) ImageZscaleCache.getValue(idbs[2], width, height, blueLimits,
blueTrans.getIntensityTransform(), blueTrans.getBias(), blueTrans.getGain(), 8);
SampleModel sm = new BandedSampleModel(DataBuffer.TYPE_BYTE, width, height, bands);
DataBufferByte dbuffer = new DataBufferByte(result, width * height);
raster = Raster.createWritableRaster(sm, dbuffer, null);
// assembly a BufferedImage
int[] bitsArray = new int[] { 8, 8, 8 };
ColorModel destCM = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), bitsArray, false, true,
Transparency.OPAQUE, raster.getSampleModel().getDataType());
BufferedImage image = new BufferedImage(destCM, raster, false, null);
// AffineTransform to zoom and vertical flip image
PaperTransform pxf = getPaperTransform();
NormalTransform xntrans = getParent().getXAxisTransform().getNormalTransform();
NormalTransform yntrans = getParent().getYAxisTransform().getNormalTransform();
Dimension2D paperSize = getParent().getSize();
double xorig = pxf.getXPtoD(xntrans.convToNR(xval) * paperSize.getWidth());
double yorig = pxf.getYPtoD(yntrans.convToNR(yval) * paperSize.getHeight());
double xscale = pxf.getScale() / xntrans.getScale() * paperSize.getWidth() * data.getXcdelt();
double yscale = pxf.getScale() / yntrans.getScale() * paperSize.getHeight() * data.getYcdelt();
AffineTransform at = new AffineTransform(xscale, 0.0, 0.0, -yscale, xorig, yorig);
// draw the image
Graphics2D g = (Graphics2D) graphics.create();
Shape clip = getPaperTransform().getPtoD(getBounds());
g.setClip(clip);
g.drawRenderedImage(image, at);
g.dispose();
}
}
Ads help maintain this website.