/* * polycasso - Cubism Artwork generator * Copyright 2009-2017 MeBigFatGuy.com * Copyright 2009-2017 Dave Brosius * Inspired by work by Roger Alsing * * Licensed 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. */ package com.mebigfatguy.polycasso; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Composite; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.awt.image.DataBufferByte; import java.awt.image.WritableRaster; /** * a class that transforms the current best polygon representation to the real image thru * a time lapse blend transformation of the images */ public class ImageCompleter implements Runnable { private static final int NUMTRANSITIONS = 500; private static final int TRANSITION_DELAY = 80; private ImageGenerator imageGenerator; private BufferedImage targetImage; private BufferedImage srcImage; private Dimension imageSize; /** * create a completer to move the image from polygon form to real form * * @param generator the image generator that this completer is working for * @param image the target image that will eventually be drawn * @param bestData the best approximation the program reached * @param size the image size */ public ImageCompleter(ImageGenerator generator, BufferedImage image, PolygonData[] bestData, Dimension size) { imageGenerator = generator; targetImage = image; imageSize = size; srcImage = new BufferedImage(imageSize.width, imageSize.height, BufferedImage.TYPE_4BYTE_ABGR); Graphics2D g2d = (Graphics2D)srcImage.getGraphics(); try { Composite srcOpaque = AlphaComposite.getInstance(AlphaComposite.SRC, 1.0f); g2d.setColor(Color.BLACK); g2d.setComposite(srcOpaque); g2d.fillRect(0, 0, imageSize.width, imageSize.height); for (PolygonData pd : bestData) { pd.draw(g2d); } } finally { g2d.dispose(); } } /** * implements the Runnable interface to gradually fade in the real image over time */ @Override public void run() { try { WritableRaster sRaster = srcImage.getRaster(); DataBufferByte sDBB = (DataBufferByte)sRaster.getDataBuffer(); byte[] sData = sDBB.getData(); WritableRaster tRaster = targetImage.getRaster(); DataBufferByte tDBB = (DataBufferByte)tRaster.getDataBuffer(); byte[] tData = tDBB.getData(); int transition = 0; do { Thread.sleep(TRANSITION_DELAY); transition++; BufferedImage intermediateImage = new BufferedImage(imageSize.width, imageSize.height, BufferedImage.TYPE_4BYTE_ABGR); WritableRaster iRaster= intermediateImage.getRaster(); DataBufferByte iDBB = (DataBufferByte)iRaster.getDataBuffer(); byte[] iData = iDBB.getData(); for (int i = 0; i < sData.length; ) { iData[i++] = (byte)0xFF; for (int c = 0; c < 3; c++) { int sC = sData[i] & 0x00FF; int tC = tData[i] & 0x00FF; int iC = sC + (((tC - sC) * transition) / NUMTRANSITIONS); iData[i] = (byte)iC; ++i; } } imageGenerator.fireImageGenerated(intermediateImage); } while ((transition < NUMTRANSITIONS) && !Thread.interrupted()); } catch (InterruptedException ie) { } } }