use of javax.imageio.metadata.IIOMetadata in project solution-finder by knewjade.
the class GifWriter method write.
@Override
public void write(List<TetfuPage> tetfuPages) throws IOException {
boolean isLoop = isInfiniteLoop;
try (ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(outputFile)) {
// imageWriterの準備
ImageWriter imageWriter = getGifImageWriter();
imageWriter.setOutput(imageOutputStream);
imageWriter.prepareWriteSequence(null);
for (TetfuPage tetfuPage : tetfuPages) {
// リセット
figGenerator.reset();
// 現在のミノを取得
ColorType colorType = tetfuPage.getColorType();
Rotate rotate = tetfuPage.getRotate();
Mino mino = ColorType.isMinoBlock(colorType) ? minoFactory.create(colorConverter.parseToBlock(colorType), rotate) : null;
int x = tetfuPage.getX();
int y = tetfuPage.getY();
// フィールドの更新
ColoredField field = tetfuPage.getField();
figGenerator.updateField(field, mino, x, y);
// ミノを置くかチェック
if (ColorType.isMinoBlock(colorType)) {
// 現在のミノの更新
figGenerator.updateMino(colorType, rotate, x, y);
// bagの更新
Piece piece = colorConverter.parseToBlock(colorType);
bag.use(piece);
}
// ネクストの更新
figGenerator.updateNext(bag.getNext(nextBoxCount));
// ホールドの更新
figGenerator.updateHold(bag.getHold());
// 画像の生成
BufferedImage image = figGenerator.fix();
// メタデータの作成
IIOMetadata metadata = createMetadata(imageWriter, image, delay, isLoop);
IIOImage iioImage = new IIOImage(image, null, metadata);
imageWriter.writeToSequence(iioImage, null);
// 無限ループの設定は最大1度までで十分
isLoop = false;
}
// imageWriterの終了処理
imageWriter.endWriteSequence();
}
}
use of javax.imageio.metadata.IIOMetadata in project artisynth_core by artisynth.
the class AnimatedGifWriter method write.
/**
* Writes a sequence of images to an animated GIF
* @param file output file
* @param frames input image sequence
* @param delayTime time between frames (s)
* @param loopCount number of times to loop (-1 for infinite)
* @throws IOException if cannot write to the output file
*/
public static void write(File file, List<? extends BufferedImage> frames, double delayTime, int loopCount) throws IOException {
ImageWriter iw;
try {
iw = ImageIO.getImageWritersByFormatName("gif").next();
} catch (Exception e) {
throw new IOException("Cannot write GIF format", e);
}
ImageOutputStream ios = ImageIO.createImageOutputStream(file);
iw.setOutput(ios);
iw.prepareWriteSequence(null);
int count = loopCount + 1;
if (count < 0) {
count = 0;
}
for (int i = 0; i < frames.size(); i++) {
BufferedImage src = frames.get(i);
ImageWriteParam iwp = iw.getDefaultWriteParam();
IIOMetadata metadata = iw.getDefaultImageMetadata(new ImageTypeSpecifier(src), iwp);
configure(metadata, delayTime, count, i);
IIOImage ii = new IIOImage(src, null, metadata);
iw.writeToSequence(ii, null);
}
iw.endWriteSequence();
ios.close();
}
use of javax.imageio.metadata.IIOMetadata in project imageio-ext by geosolutions-it.
the class TIFFReadTest method readWithEmptyTiles.
@Test
public void readWithEmptyTiles() throws IOException {
// This input image is a 1440x720 image. However, the right half of the image
// is made of empty tiles filled with nodata
final File file = TestData.file(this, "emptyTiles.tif");
final TIFFImageReader reader = (TIFFImageReader) new TIFFImageReaderSpi().createReaderInstance();
FileImageInputStream inputStream = new FileImageInputStream(file);
try {
reader.setInput(inputStream);
ImageReadParam param = new ImageReadParam();
// Setting up a region to fall in the half of the image containing empty tiles
param.setSourceRegion(new Rectangle(360, 0, 720, 720));
BufferedImage image = reader.read(0, param);
Assert.assertEquals(720, image.getWidth());
Assert.assertEquals(720, image.getHeight());
IIOMetadata metadata = reader.getImageMetadata(0);
Node rootNode = metadata.getAsTree(metadata.getNativeMetadataFormatName());
double noDataValue = getNoDataValue(rootNode);
// get it from the core common metadata too
CoreCommonImageMetadata ccm = (CoreCommonImageMetadata) metadata;
double[] noDataArray = ccm.getNoData();
assertNotNull(noDataArray);
assertEquals(noDataArray[0], noDataValue, 0d);
assertEquals(noDataArray[1], noDataValue, 0d);
// Check that the value is noData (the empty Tiles are filled with NoData)
double val = image.getData().getSampleDouble(719, 0, 0);
assertEquals(Double.toString(noDataValue), Double.toString(val));
image.flush();
image = null;
} catch (Exception e) {
// If an exception occurred the logger catch the exception and print
// the message
logger.log(Level.SEVERE, e.getMessage(), e);
} finally {
if (inputStream != null) {
inputStream.flush();
inputStream.close();
}
if (reader != null) {
reader.dispose();
}
}
}
use of javax.imageio.metadata.IIOMetadata in project imageio-ext by geosolutions-it.
the class PNMImageWriter method write.
public void write(IIOMetadata streamMetadata, IIOImage image, ImageWriteParam param) throws IOException {
clearAbortRequest();
processImageStarted(0);
if (param == null)
param = getDefaultWriteParam();
RenderedImage input = null;
Raster inputRaster = null;
boolean writeRaster = image.hasRaster();
Rectangle sourceRegion = param.getSourceRegion();
SampleModel sampleModel = null;
ColorModel colorModel = null;
if (writeRaster) {
inputRaster = image.getRaster();
sampleModel = inputRaster.getSampleModel();
if (sourceRegion == null)
sourceRegion = inputRaster.getBounds();
else
sourceRegion = sourceRegion.intersection(inputRaster.getBounds());
} else {
input = image.getRenderedImage();
sampleModel = input.getSampleModel();
colorModel = input.getColorModel();
Rectangle rect = new Rectangle(input.getMinX(), input.getMinY(), input.getWidth(), input.getHeight());
if (sourceRegion == null)
sourceRegion = rect;
else
sourceRegion = sourceRegion.intersection(rect);
}
if (sourceRegion.isEmpty())
throw new RuntimeException(I18N.getString("PNMImageWrite1"));
ImageUtil.canEncodeImage(this, colorModel, sampleModel);
int scaleX = param.getSourceXSubsampling();
int scaleY = param.getSourceYSubsampling();
int xOffset = param.getSubsamplingXOffset();
int yOffset = param.getSubsamplingYOffset();
sourceRegion.translate(xOffset, yOffset);
sourceRegion.width -= xOffset;
sourceRegion.height -= yOffset;
int w = (sourceRegion.width + scaleX - 1) / scaleX;
int h = (sourceRegion.height + scaleY - 1) / scaleY;
int tileWidth = sampleModel.getWidth();
// Raw data can only handle bytes, everything greater must be ASCII.
int[] sampleSize = sampleModel.getSampleSize();
int[] sourceBands = param.getSourceBands();
int numBands = sampleModel.getNumBands();
if (sourceBands != null) {
sampleModel = sampleModel.createSubsetSampleModel(sourceBands);
colorModel = null;
numBands = sampleModel.getNumBands();
} else {
sourceBands = new int[numBands];
for (int i = 0; i < numBands; i++) sourceBands[i] = i;
}
// Colormap populated for non-bilevel IndexColorModel only.
byte[] reds = null;
byte[] greens = null;
byte[] blues = null;
// Flag indicating that PB data should be inverted before writing.
boolean isPBMInverted = false;
if (numBands == 1) {
if (colorModel instanceof IndexColorModel) {
IndexColorModel icm = (IndexColorModel) colorModel;
int mapSize = icm.getMapSize();
if (mapSize < (1 << sampleSize[0]))
throw new RuntimeException(I18N.getString("PNMImageWrite2"));
if (sampleSize[0] == 1) {
variant = PBM_RAW;
// Set PBM inversion flag if 1 maps to a higher color
// value than 0: PBM expects white-is-zero so if this
// does not obtain then inversion needs to occur.
isPBMInverted = icm.getRed(1) > icm.getRed(0);
} else {
variant = PPM_RAW;
reds = new byte[mapSize];
greens = new byte[mapSize];
blues = new byte[mapSize];
icm.getReds(reds);
icm.getGreens(greens);
icm.getBlues(blues);
}
} else if (sampleSize[0] == 1) {
variant = PBM_RAW;
} else if (sampleSize[0] <= 8) {
variant = PGM_RAW;
} else {
variant = PGM_ASCII;
}
} else if (numBands == 3) {
if (sampleSize[0] <= 8 && sampleSize[1] <= 8 && sampleSize[2] <= 8) {
// all 3 bands must be <= 8
variant = PPM_RAW;
} else {
variant = PPM_ASCII;
}
} else {
throw new RuntimeException(I18N.getString("PNMImageWrite3"));
}
IIOMetadata inputMetadata = image.getMetadata();
ImageTypeSpecifier imageType;
if (colorModel != null) {
imageType = new ImageTypeSpecifier(colorModel, sampleModel);
} else {
int dataType = sampleModel.getDataType();
switch(numBands) {
case 1:
imageType = ImageTypeSpecifier.createGrayscale(sampleSize[0], dataType, false);
break;
case 3:
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
imageType = ImageTypeSpecifier.createInterleaved(cs, new int[] { 0, 1, 2 }, dataType, false, false);
break;
default:
throw new IIOException("Cannot encode image with " + numBands + " bands!");
}
}
PNMMetadata metadata;
if (inputMetadata != null) {
// Convert metadata.
metadata = (PNMMetadata) convertImageMetadata(inputMetadata, imageType, param);
} else {
// Use default.
metadata = (PNMMetadata) getDefaultImageMetadata(imageType, param);
}
// Read parameters
boolean isRawPNM;
if (param instanceof PNMImageWriteParam) {
isRawPNM = ((PNMImageWriteParam) param).getRaw();
} else {
isRawPNM = metadata.isRaw();
}
maxValue = metadata.getMaxValue();
for (int i = 0; i < sampleSize.length; i++) {
int v = (1 << sampleSize[i]) - 1;
if (v > maxValue) {
maxValue = v;
}
}
if (isRawPNM) {
// Raw output is desired.
int maxBitDepth = metadata.getMaxBitDepth();
if (!isRaw(variant) && maxBitDepth <= 8) {
// Current variant is ASCII and the bit depth is acceptable
// so convert to RAW variant by adding '3' to variant.
variant += 0x3;
} else if (isRaw(variant) && maxBitDepth > 8) {
// Current variant is RAW and the bit depth it too large for
// RAW so convert to ASCII.
variant -= 0x3;
}
// Omitted cases are (variant == RAW && max <= 8) and
// (variant == ASCII && max > 8) neither of which requires action.
} else if (isRaw(variant)) {
// Raw output is NOT desired so convert to ASCII
variant -= 0x3;
}
// Write PNM file.
// magic value: 'P'
stream.writeByte('P');
stream.writeByte(variant);
stream.write(lineSeparator);
// comment line
stream.write(COMMENT.getBytes());
// Write the comments provided in the metadata
Iterator comments = metadata.getComments();
if (comments != null) {
while (comments.hasNext()) {
stream.write(lineSeparator);
String comment = "# " + (String) comments.next();
stream.write(comment.getBytes());
}
}
stream.write(lineSeparator);
// width
writeInteger(stream, w);
stream.write(SPACE);
// height
writeInteger(stream, h);
// Write sample max value for non-binary images
if ((variant != PBM_RAW) && (variant != PBM_ASCII)) {
stream.write(lineSeparator);
writeInteger(stream, maxValue);
}
// last header value and the start of the raw data.
if (variant == PBM_RAW || variant == PGM_RAW || variant == PPM_RAW) {
stream.write('\n');
}
// Set flag for optimal image writing case: row-packed data with
// correct band order if applicable.
boolean writeOptimal = false;
if (variant == PBM_RAW && sampleModel.getTransferType() == DataBuffer.TYPE_BYTE && sampleModel instanceof MultiPixelPackedSampleModel) {
MultiPixelPackedSampleModel mppsm = (MultiPixelPackedSampleModel) sampleModel;
int originX = 0;
if (writeRaster)
originX = inputRaster.getMinX();
else
originX = input.getMinX();
// Must have left-aligned bytes with unity bit stride.
if (mppsm.getBitOffset((sourceRegion.x - originX) % tileWidth) == 0 && mppsm.getPixelBitStride() == 1 && scaleX == 1)
writeOptimal = true;
} else if ((variant == PGM_RAW || variant == PPM_RAW) && sampleModel instanceof ComponentSampleModel && !(colorModel instanceof IndexColorModel)) {
ComponentSampleModel csm = (ComponentSampleModel) sampleModel;
// Pixel stride must equal band count.
if (csm.getPixelStride() == numBands && scaleX == 1) {
writeOptimal = true;
// Band offsets must equal band indices.
if (variant == PPM_RAW) {
int[] bandOffsets = csm.getBandOffsets();
for (int b = 0; b < numBands; b++) {
if (bandOffsets[b] != b) {
writeOptimal = false;
break;
}
}
}
}
}
// Write using an optimal approach if possible.
if (writeOptimal) {
int bytesPerRow = variant == PBM_RAW ? (w + 7) / 8 : w * sampleModel.getNumBands();
byte[] bdata = null;
byte[] invertedData = new byte[bytesPerRow];
// Loop over tiles to minimize cobbling.
for (int j = 0; j < sourceRegion.height; j++) {
if (abortRequested())
break;
Raster lineRaster = null;
if (writeRaster) {
lineRaster = inputRaster.createChild(sourceRegion.x, j, sourceRegion.width, 1, 0, 0, null);
} else {
lineRaster = input.getData(new Rectangle(sourceRegion.x, sourceRegion.y + j, w, 1));
lineRaster = lineRaster.createTranslatedChild(0, 0);
}
bdata = ((DataBufferByte) lineRaster.getDataBuffer()).getData();
sampleModel = lineRaster.getSampleModel();
int offset = 0;
if (sampleModel instanceof ComponentSampleModel) {
offset = ((ComponentSampleModel) sampleModel).getOffset(lineRaster.getMinX() - lineRaster.getSampleModelTranslateX(), lineRaster.getMinY() - lineRaster.getSampleModelTranslateY());
} else if (sampleModel instanceof MultiPixelPackedSampleModel) {
offset = ((MultiPixelPackedSampleModel) sampleModel).getOffset(lineRaster.getMinX() - lineRaster.getSampleModelTranslateX(), lineRaster.getMinX() - lineRaster.getSampleModelTranslateY());
}
if (isPBMInverted) {
for (int k = offset, m = 0; m < bytesPerRow; k++, m++) invertedData[m] = (byte) ~bdata[k];
bdata = invertedData;
offset = 0;
}
stream.write(bdata, offset, bytesPerRow);
processImageProgress(100.0F * j / sourceRegion.height);
}
// Write all buffered bytes and return.
stream.flush();
if (abortRequested())
processWriteAborted();
else
processImageComplete();
return;
}
// Buffer for 1 rows of original pixels
int size = sourceRegion.width * numBands;
int[] pixels = new int[size];
// Also allocate a buffer to hold the data to be written to the file,
// so we can use array writes.
byte[] bpixels = reds == null ? new byte[w * numBands] : new byte[w * 3];
// The index of the sample being written, used to
// place a line separator after every 16th sample in
// ASCII mode. Not used in raw mode.
int count = 0;
// Process line by line
int lastRow = sourceRegion.y + sourceRegion.height;
for (int row = sourceRegion.y; row < lastRow; row += scaleY) {
if (abortRequested())
break;
// Grab the pixels
Raster src = null;
if (writeRaster)
src = inputRaster.createChild(sourceRegion.x, row, sourceRegion.width, 1, sourceRegion.x, row, sourceBands);
else
src = input.getData(new Rectangle(sourceRegion.x, row, sourceRegion.width, 1));
src.getPixels(sourceRegion.x, row, sourceRegion.width, 1, pixels);
if (isPBMInverted)
for (int i = 0; i < size; i += scaleX) bpixels[i] ^= 1;
switch(variant) {
case PBM_ASCII:
for (int i = 0; i < size; i += scaleX) {
if ((count++ % 16) == 0)
stream.write(lineSeparator);
else
stream.write(SPACE);
writeInteger(stream, isPBMInverted ? (byte) ~pixels[i] : pixels[i]);
}
stream.write(lineSeparator);
break;
case PGM_ASCII:
for (int i = 0; i < size; i += scaleX) {
if ((count++ % 16) == 0)
stream.write(lineSeparator);
else
stream.write(SPACE);
writeInteger(stream, pixels[i]);
}
stream.write(lineSeparator);
break;
case PPM_ASCII:
if (reds == null) {
for (int i = 0; i < size; i += scaleX * numBands) {
for (int j = 0; j < numBands; j++) {
if ((count++ % 16) == 0)
stream.write(lineSeparator);
else
stream.write(SPACE);
writeInteger(stream, pixels[i + j]);
}
}
} else {
for (int i = 0; i < size; i += scaleX) {
if ((count++ % 5) == 0)
stream.write(lineSeparator);
else
stream.write(SPACE);
writeInteger(stream, (reds[pixels[i]] & 0xFF));
stream.write(SPACE);
writeInteger(stream, (greens[pixels[i]] & 0xFF));
stream.write(SPACE);
writeInteger(stream, (blues[pixels[i]] & 0xFF));
}
}
stream.write(lineSeparator);
break;
case PBM_RAW:
// 8 pixels packed into 1 byte, the leftovers are padded.
int kdst = 0;
int b = 0;
int pos = 7;
for (int i = 0; i < size; i += scaleX) {
b |= pixels[i] << pos;
pos--;
if (pos == -1) {
bpixels[kdst++] = (byte) b;
b = 0;
pos = 7;
}
}
if (pos != 7)
bpixels[kdst++] = (byte) b;
stream.write(bpixels, 0, kdst);
break;
case PGM_RAW:
for (int i = 0, j = 0; i < size; i += scaleX) {
bpixels[j++] = (byte) (pixels[i]);
}
stream.write(bpixels, 0, w);
break;
case PPM_RAW:
if (reds == null) {
// no need to expand
for (int i = 0, k = 0; i < size; i += scaleX * numBands) {
for (int j = 0; j < numBands; j++) bpixels[k++] = (byte) (pixels[i + j] & 0xFF);
}
} else {
for (int i = 0, j = 0; i < size; i += scaleX) {
bpixels[j++] = reds[pixels[i]];
bpixels[j++] = greens[pixels[i]];
bpixels[j++] = blues[pixels[i]];
}
}
stream.write(bpixels, 0, bpixels.length);
break;
}
processImageProgress(100.0F * (row - sourceRegion.y) / sourceRegion.height);
}
// Force all buffered bytes to be written out.
stream.flush();
if (abortRequested())
processWriteAborted();
else
processImageComplete();
}
use of javax.imageio.metadata.IIOMetadata in project imageio-ext by geosolutions-it.
the class TIFFBaseJPEGCompressor method encode.
public final int encode(byte[] b, int off, int width, int height, int[] bitsPerSample, int scanlineStride) throws IOException {
if (this.JPEGWriter == null) {
throw new IIOException("JPEG writer has not been initialized!");
}
if (!((bitsPerSample.length == 3 && bitsPerSample[0] == 8 && bitsPerSample[1] == 8 && bitsPerSample[2] == 8) || (bitsPerSample.length == 1 && bitsPerSample[0] == 8))) {
throw new IIOException("Can only JPEG compress 8- and 24-bit images!");
}
// Set the stream.
ImageOutputStream ios;
// usingCodecLib && !writeAbbreviatedStream
long initialStreamPosition;
if (usingCodecLib && !writeAbbreviatedStream) {
ios = stream;
initialStreamPosition = stream.getStreamPosition();
} else {
// is using a stream on the native side which cannot be reset.
if (baos == null) {
baos = new IIOByteArrayOutputStream();
} else {
baos.reset();
}
ios = new MemoryCacheImageOutputStream(baos);
initialStreamPosition = 0L;
}
JPEGWriter.setOutput(ios);
// Create a DataBuffer.
DataBufferByte dbb;
if (off == 0 || usingCodecLib) {
dbb = new DataBufferByte(b, b.length);
} else {
//
// Workaround for bug in core Java Image I/O JPEG
// ImageWriter which cannot handle non-zero offsets.
//
int bytesPerSegment = scanlineStride * height;
byte[] btmp = new byte[bytesPerSegment];
System.arraycopy(b, off, btmp, 0, bytesPerSegment);
dbb = new DataBufferByte(btmp, bytesPerSegment);
off = 0;
}
// Set up the ColorSpace.
int[] offsets;
ColorSpace cs;
if (bitsPerSample.length == 3) {
offsets = new int[] { off, off + 1, off + 2 };
cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
} else {
offsets = new int[] { off };
cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
}
// Create the ColorModel.
ColorModel cm = new ComponentColorModel(cs, false, false, Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
// Create the SampleModel.
SampleModel sm = new PixelInterleavedSampleModel(DataBuffer.TYPE_BYTE, width, height, bitsPerSample.length, scanlineStride, offsets);
// Create the WritableRaster.
WritableRaster wras = Raster.createWritableRaster(sm, dbb, new Point(0, 0));
// Create the BufferedImage.
BufferedImage bi = new BufferedImage(cm, wras, false, null);
// Get the pruned JPEG image metadata (may be null).
IIOMetadata imageMetadata = getImageMetadata(writeAbbreviatedStream);
// Compress the image into the output stream.
int compDataLength;
if (usingCodecLib && !writeAbbreviatedStream) {
// Write complete JPEG stream
JPEGWriter.write(null, new IIOImage(bi, null, imageMetadata), JPEGParam);
compDataLength = (int) (stream.getStreamPosition() - initialStreamPosition);
} else {
if (writeAbbreviatedStream) {
// Write abbreviated JPEG stream
// First write the tables-only data.
JPEGWriter.prepareWriteSequence(JPEGStreamMetadata);
ios.flush();
// Rewind to the beginning of the byte array.
baos.reset();
// Write the abbreviated image data.
IIOImage image = new IIOImage(bi, null, imageMetadata);
JPEGWriter.writeToSequence(image, JPEGParam);
JPEGWriter.endWriteSequence();
} else {
// Write complete JPEG stream
JPEGWriter.write(null, new IIOImage(bi, null, imageMetadata), JPEGParam);
}
compDataLength = baos.size();
baos.writeTo(stream);
baos.reset();
}
return compDataLength;
}
Aggregations