org.apache.xmlgraphics.image.loader.impl.ImageConverterG2D2Bitmap Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.apache.fop Show documentation
Show all versions of org.apache.fop Show documentation
The core maven build properties
The newest version!
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* $Id: ImageConverterG2D2Bitmap.java 1754511 2016-07-29 13:09:37Z ssteiner $ */
package org.apache.xmlgraphics.image.loader.impl;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.PixelInterleavedSampleModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.util.Map;
import org.apache.xmlgraphics.image.GraphicsConstants;
import org.apache.xmlgraphics.image.loader.Image;
import org.apache.xmlgraphics.image.loader.ImageFlavor;
import org.apache.xmlgraphics.image.loader.ImageProcessingHints;
import org.apache.xmlgraphics.image.loader.ImageSize;
import org.apache.xmlgraphics.java2d.color.DeviceCMYKColorSpace;
import org.apache.xmlgraphics.util.UnitConv;
/**
* This ImageConverter converts Graphics2D images to a BufferedImage.
*/
public class ImageConverterG2D2Bitmap extends AbstractImageConverter {
/** {@inheritDoc} */
public Image convert(Image src, Map hints) {
checkSourceFlavor(src);
assert src instanceof ImageGraphics2D;
ImageGraphics2D g2dImage = (ImageGraphics2D)src;
Object formatIntent = hints.get(ImageProcessingHints.BITMAP_TYPE_INTENT);
int bitsPerPixel = 24;
if (ImageProcessingHints.BITMAP_TYPE_INTENT_GRAY.equals(formatIntent)) {
bitsPerPixel = 8;
} else if (ImageProcessingHints.BITMAP_TYPE_INTENT_MONO.equals(formatIntent)) {
bitsPerPixel = 1;
}
Object transparencyIntent = hints.get(ImageProcessingHints.TRANSPARENCY_INTENT);
boolean withAlpha = true;
if (ImageProcessingHints.TRANSPARENCY_INTENT_IGNORE.equals(transparencyIntent)) {
withAlpha = false;
}
int resolution = GraphicsConstants.DEFAULT_SAMPLE_DPI;
Number res = (Number)hints.get(ImageProcessingHints.TARGET_RESOLUTION);
if (res != null) {
resolution = res.intValue();
}
boolean cmyk = Boolean.TRUE.equals(hints.get("CMYK"));
BufferedImage bi = paintToBufferedImage(g2dImage, bitsPerPixel, withAlpha, resolution, cmyk);
ImageBuffered bufImage = new ImageBuffered(src.getInfo(), bi, null);
return bufImage;
}
/**
* Paints a Graphics2D image on a BufferedImage and returns this bitmap.
* @param g2dImage the Graphics2D image
* @param bitsPerPixel the desired number of bits per pixel (supported: 1, 8, 24)
* @param withAlpha true if the generated image should have an alpha channel
* @param resolution the requested bitmap resolution
* @return the newly created BufferedImage
*/
protected BufferedImage paintToBufferedImage(ImageGraphics2D g2dImage,
int bitsPerPixel, boolean withAlpha, int resolution, boolean cmyk) {
ImageSize size = g2dImage.getSize();
RenderingHints additionalHints = null;
int bmw = (int)Math.ceil(UnitConv.mpt2px(size.getWidthMpt(), resolution));
int bmh = (int)Math.ceil(UnitConv.mpt2px(size.getHeightMpt(), resolution));
BufferedImage bi;
switch (bitsPerPixel) {
case 1:
bi = new BufferedImage(bmw, bmh, BufferedImage.TYPE_BYTE_BINARY);
withAlpha = false;
//withAlpha is ignored in this case
additionalHints = new RenderingHints(null);
//The following usually has no effect but some class libraries might support it
additionalHints.put(RenderingHints.KEY_DITHERING,
RenderingHints.VALUE_DITHER_ENABLE);
break;
case 8:
if (withAlpha) {
bi = createGrayBufferedImageWithAlpha(bmw, bmh);
} else {
bi = new BufferedImage(bmw, bmh, BufferedImage.TYPE_BYTE_GRAY);
}
break;
default:
if (withAlpha) {
bi = new BufferedImage(bmw, bmh, BufferedImage.TYPE_INT_ARGB);
} else {
if (cmyk) {
ComponentColorModel ccm = new ComponentColorModel(
new DeviceCMYKColorSpace(), false, false, 1, DataBuffer.TYPE_BYTE);
int[] bands = {0, 1, 2, 3};
PixelInterleavedSampleModel sm = new PixelInterleavedSampleModel(
DataBuffer.TYPE_BYTE, bmw, bmh, 4, bmw * 4, bands);
WritableRaster raster = WritableRaster.createWritableRaster(sm, new Point(0, 0));
bi = new BufferedImage(ccm, raster, false, null);
} else {
bi = new BufferedImage(bmw, bmh, BufferedImage.TYPE_INT_RGB);
}
}
}
Graphics2D g2d = bi.createGraphics();
try {
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
setRenderingHintsForBufferedImage(g2d);
if (additionalHints != null) {
g2d.addRenderingHints(additionalHints);
}
g2d.setBackground(Color.white);
g2d.setColor(Color.black);
if (!withAlpha) {
g2d.clearRect(0, 0, bmw, bmh);
}
/* debug code
int off = 2;
g2d.drawLine(off, 0, off, bmh);
g2d.drawLine(bmw - off, 0, bmw - off, bmh);
g2d.drawLine(0, off, bmw, off);
g2d.drawLine(0, bmh - off, bmw, bmh - off);
*/
double sx = (double)bmw / size.getWidthMpt();
double sy = (double)bmh / size.getHeightMpt();
g2d.scale(sx, sy);
//Paint the image on the BufferedImage
Rectangle2D area = new Rectangle2D.Double(
0.0, 0.0, size.getWidthMpt(), size.getHeightMpt());
g2dImage.getGraphics2DImagePainter().paint(g2d, area);
} finally {
g2d.dispose();
}
return bi;
}
private static BufferedImage createGrayBufferedImageWithAlpha(int width, int height) {
BufferedImage bi;
boolean alphaPremultiplied = true;
int bands = 2;
int[] bits = new int[bands];
for (int i = 0; i < bands; i++) {
bits[i] = 8;
}
ColorModel cm = new ComponentColorModel(
ColorSpace.getInstance(ColorSpace.CS_GRAY),
bits,
true, alphaPremultiplied,
Transparency.TRANSLUCENT,
DataBuffer.TYPE_BYTE);
WritableRaster wr = Raster.createInterleavedRaster(
DataBuffer.TYPE_BYTE,
width, height, bands,
new Point(0, 0));
bi = new BufferedImage(cm, wr, alphaPremultiplied, null);
return bi;
}
/**
* Sets rendering hints on the Graphics2D created for painting to a BufferedImage. Subclasses
* can modify the settings to customize the behaviour.
* @param g2d the Graphics2D instance
*/
protected void setRenderingHintsForBufferedImage(Graphics2D g2d) {
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
}
/** {@inheritDoc} */
public ImageFlavor getSourceFlavor() {
return ImageFlavor.GRAPHICS2D;
}
/** {@inheritDoc} */
public ImageFlavor getTargetFlavor() {
return ImageFlavor.BUFFERED_IMAGE;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy