--- /dev/null 2014-02-05 01:06:41.000000000 +0800 +++ new/src/share/sample/stream/parallel/ImageTransform.java 2014-02-05 01:06:41.064680500 +0800 @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of Oracle nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS + * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This source code is provided to illustrate the usage of a given feature + * or technique and has been deliberately simplified. Additional steps + * required for a production-quality application, such as security checks, + * input validation and proper error handling, might not be present in + * this sample code. + */ +package stream.parallel; + +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import static java.awt.image.BufferedImage.TYPE_INT_RGB; +import java.io.File; +import java.util.stream.IntStream; +import javax.imageio.ImageIO; + +/** + * This demo shows parallel geometrical transformations of images.The operations + * of image include rotation, shift, scale, inversion. + * + * @author tyan + */ +public class ImageTransform { + + public static void main(String[] args) { + try { + if (args.length < 5) { + usage(); + return; + } + int argPos = 0; + int oprand = 0; + String command = ""; + String inputFile = "", outputFile = ""; + boolean yes = true; + while (argPos < args.length) { + switch (args[argPos++]) { + case "-ls": + case "-rs": + yes = args[argPos - 1].equals("-ls"); + oprand = Integer.parseInt(args[argPos++]); + command = "shift"; + break; + case "-cl": + case "-ccl": + yes = args[argPos - 1].equals("-cl"); + oprand = Integer.parseInt(args[argPos++]); + command = "rotate"; + break; + case "-zi": + case "-zo": + oprand = Integer.parseInt(args[argPos++]); + command = "zoom"; + break; + case "-iv": + command = "invert"; + break; + case "-i": + inputFile = args[argPos++]; + break; + case "-o": + outputFile = args[argPos++]; + break; + default: + usage(); + return; + } + } + if (inputFile.equals("") || outputFile.equals("")) { + throw new Exception("Input/Output file is needed"); + } + File inFile = new File(inputFile); + File outFile = new File(outputFile); + BufferedImage in = ImageIO.read(inFile); + int newWidth = in.getWidth(); + int newHeight = in.getHeight(); + if (command.equals("zoom")) { + double magnitude = oprand / 100.0; + newWidth = (int) (newWidth * magnitude); + newHeight = (int) (newHeight * magnitude); + } else if (command.equals("rotate")) { + int perimeter = (int)Math.sqrt( + newWidth * newWidth + newHeight * newHeight); + newWidth = perimeter; + newHeight = perimeter; + } + BufferedImage out = new BufferedImage(newWidth, newHeight, TYPE_INT_RGB); + switch (command) { + case "shift": + shift(in, out, yes, oprand); + break; + case "rotate": + rotate(in, out, yes, oprand); + break; + case "zoom": + zoom(in, out, oprand); + break; + case "invert": + invert(in, out); + break; + } + ImageIO.write(out, "jpg", outFile); + } catch (Exception ex) { + usage(); + } + } + + /** + * Rotate an image as given angle. + * @param in input image + * @param out output image + * @param clockwise true clockwise + * false counter-clockwise + * @param angle angle that image will rotate + */ + public static void rotate(BufferedImage in, BufferedImage out, + boolean clockwise, int angle) { + int width = (int) in.getWidth(); + int height = (int) in.getHeight(); + int oldCenterX = width / 2; + int oldCenterY = height / 2; + int centerXDelta = (int)out.getWidth() / 2 - oldCenterX; + int centerYDelta = (int)out.getHeight() / 2 - oldCenterY; + double rotateV = clockwise ? angle : -angle; + IntStream.range(0, width).parallel().forEach(x -> { + double[] columns = IntStream.range(0, height).flatMap( + i -> IntStream.of(x, i)).mapToDouble(i -> i).toArray(); + AffineTransform.getRotateInstance(Math.toRadians(rotateV), + oldCenterX, oldCenterY).transform(columns, 0, columns, 0, height); + IntStream.range(0, height).forEach(y -> out.setRGB( + (int)columns[2 * y] + centerXDelta, + (int)columns[2 *y + 1] + centerYDelta, + in.getRGB(x, y))); + }); + } + + /** + * Shift an image horizontally. + * @param in input image + * @param out output image + * @param left true left shift + * false right shift + * @param length size that image shifts + */ + public static void shift(BufferedImage in, BufferedImage out, + boolean left, int length) { + int width = (int) out.getWidth(); + int height = (int) out.getHeight(); + int leftShift = left ? length % width : width - length % width; + IntStream.range(0, width).parallel().forEach(x -> { + IntStream.range(0, height).forEach(y -> { + int newX = x >= leftShift ? x - leftShift : width + x - leftShift; + out.setRGB(newX, y, in.getRGB(x, y)); + }); + }); + } + + /** + * Zoom in/out an image. + * @param in input image + * @param out output image + * @param percentage percentage that image will zoom in/out. + */ + public static void zoom(BufferedImage in, BufferedImage out, int percentage) { + int width = (int) out.getWidth(); + int height = (int) out.getHeight(); + double magnitude = percentage / 100.0; + IntStream.range(0, width).parallel().forEach(x -> { + IntStream.range(0, height).forEach(y -> { + int oldX = (int) (x / magnitude); + int oldY = (int) (y / magnitude); + out.setRGB(x, y, in.getRGB(oldX, oldY)); + }); + }); + } + + /** + * Invert color of an image. + * @param in input image + * @param out output image + */ + public static void invert(BufferedImage in, BufferedImage out) { + int width = (int) out.getWidth(); + int height = (int) out.getHeight(); + IntStream.range(0, width).parallel().forEach(x -> { + IntStream.range(0, height).forEach(y -> { + out.setRGB(x, y, in.getRGB(x, y) ^ 0xffffff); + }); + }); + } + + /** + * Usage of this program + */ + public static void usage() { + System.out.println("Usage: java ImageTransform " + + "[-rs size|-ls size|-rr angle|-lr angle|-zi percentage|-zo precentage|-iv] " + + "-i InputFile -o OutputFile"); + } +}