--- /dev/null 2014-02-02 21:38:55.000000000 +0800 +++ new/src/share/sample/stream/parallel/ImageTransform.java 2014-02-02 21:38:54.000000000 +0800 @@ -0,0 +1,233 @@ +/* + * 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.image.BufferedImage; +import static java.awt.image.BufferedImage.TYPE_INT_RGB; +import java.io.File; +import java.util.stream.IntStream; +import javax.imageio.ImageIO; +import static stream.parallel.RandomPrimeNumber.usage; + +/** + * 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 "-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("rorate")) { + int max = Math.max(newWidth, newWidth); + newWidth = max; + newHeight = max; + } + BufferedImage out = new BufferedImage(newWidth, newHeight, TYPE_INT_RGB); + if(!command.equals("invert") && oprand <= 0) { + throw new Exception("Value must be a positive number"); + } + switch (command) { + case "shift": + shift(in, out, yes, oprand); + break; + case "rotate": + rotate(in, out, yes, oprand); + break; + case "zoom": + zoom(in, out, oprand / 100.0); + 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 centerX = width / 2; + int centerY = height / 2; + double rotateV = (clockwise ? 360 - angle : angle) / 180.0 * Math.PI; + IntStream.range(0, width).parallel().forEach(x -> { + IntStream.range(0, height).parallel().forEach(y -> { + int newX = (int) (centerX + (x - centerX) * Math.cos(rotateV) + + (y - centerY) * Math.sin(rotateV)); + int newY = (int) (centerY + (x - centerX) * Math.sin(rotateV) + + (y - centerY) * Math.cos(rotateV)); + if (newX >= 0 && newX < width && newY >= 0 && newY < height) { + out.setRGB(newX, newY, 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).parallel().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 magnitude scale of original image. + */ + public static void zoom(BufferedImage in, BufferedImage out, + double magnitude) { + int width = (int) out.getWidth(); + int height = (int) out.getHeight(); + IntStream.range(0, width).parallel().forEach(x -> { + IntStream.range(0, height).parallel().forEach(y -> { + int oldX = (int) (x / magnitude); + int oldY = (int) (y / magnitude); + if (oldX < in.getWidth() && oldY < in.getHeight()) { + 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).parallel().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|" + + "-cl angle|-ccl angle|-zo percentage|-zo precentage|-iv} " + + "-i InputFile -o OutputFile"); + } +}