package utils; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.Point; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; import java.awt.image.WritableRaster; import java.io.BufferedOutputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.LineNumberReader; import javax.imageio.ImageIO; public class image_functions { /*Creates a copy of {image}, with same color model but * a newly allocated raster array. */ public static BufferedImage copy_image (BufferedImage image) { ColorModel cm = image.getColorModel(); boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); WritableRaster raster = image.copyData(null); return new BufferedImage(cm, raster, isAlphaPremultiplied, null); } /*Wites the given BufferedImage {image} (which must be of TYPE_USHORT_GRAY) * to disk as a raw 16-bit PGM-format image file called "{name}". */ public static void write_gray_image_as_pgm (BufferedImage image, String name) { File f = new File(name); assert(image.getType() == BufferedImage.TYPE_USHORT_GRAY); try { /*Opening output stream*/ DataOutputStream stream = new DataOutputStream(new BufferedOutputStream (new FileOutputStream(f))); /* Getting image dimensions */ int w = image.getWidth(null); int h = image.getHeight(null); /* Writing PPM header */ stream.write('P'); stream.write('5'); stream.write('\n'); stream.write(Integer.toString(w).getBytes()); stream.write(' '); stream.write(Integer.toString(h).getBytes()); stream.write('\n'); stream.write(Integer.toString(65535).getBytes()); stream.write('\n'); short[] pixels = (short [])image.getData().getDataElements(0, 0, w, h, null); /* Write each row of pixels */ for (int k = 0; k < pixels.length; k++) { int pixel = pixels[k]; int v1 = (pixel & 0x00ff); int v2 = (pixel & 0xff00) >> 8; //System.err.printf("v1: %d, v2: %d, pixel: %d\n", v1, v2, pixel); stream.write(v2); stream.write(v1); } stream.flush(); /*Closing the output stream*/ stream.close(); } catch (IOException e) { System.err.println("Error: image writing failed"); } } /*Converts the given BufferedImage {image} (which must be of TYPE_INT_ARGB) * to grayscale and writes it to disk as a raw 8-bit PGM-format image * file called "{name}". */ public static void write_rgb_image_as_pgm (BufferedImage image, String name) { File f = new File(name); assert(image.getType() == BufferedImage.TYPE_INT_ARGB); try { /*Opening output stream*/ DataOutputStream stream = new DataOutputStream(new BufferedOutputStream (new FileOutputStream(f))); /* Getting image dimensions */ int w = image.getWidth(null); int h = image.getHeight(null); /* Writing PPM header */ stream.write('P'); stream.write('5'); stream.write('\n'); stream.write(Integer.toString(w).getBytes()); stream.write(' '); stream.write(Integer.toString(h).getBytes()); stream.write('\n'); stream.write(Integer.toString(255).getBytes()); stream.write('\n'); /* Write each row of pixels */ for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { int pixel = image.getRGB(x, y); double R = 0.5 + (double)((pixel & 0xff0000) >> 16); double G = 0.5 + (double)((pixel & 0xff00) >> 8); double B = 0.5 + (double)(pixel & 0xff); int v = (int)Math.floor(0.299*R + 0.587*G + 0.114*B); if (v < 0) { v = 0;} if (v > 255) { v = 255;} stream.write(v); } } stream.flush(); /*Closing the output stream*/ stream.close(); } catch (IOException e) { System.err.println("Error: image writing failed"); } } /*Get a grey level image from a color image.*/ public static double[] get_grey_double_from_rgb_image (BufferedImage image) { assert(image.getType() == BufferedImage.TYPE_INT_ARGB); int width = image.getWidth(null); int height = image.getHeight(null); double[] grey = new double[width*height]; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int pixel = image.getRGB(x, y); int position = y * width + x; double R = (pixel >> 16) & 255; double G = (pixel >> 8) & 255; double B = (pixel & 255); R = (R + 0.5)/256.0; G = (G + 0.5)/256.0; B = (B + 0.5)/256.0; grey[position] = 0.299*R + 0.587*G + 0.114*B; } } return grey; } public static double[] get_grey_image_normal (BufferedImage image) { int width = image.getWidth(null); int height = image.getHeight(null); double[] grey = new double[width*height]; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int pixel = image.getRGB(x, y); int position = y * width + x; double R = (pixel >> 16) & 255; double G = (pixel >> 8) & 255; double B = (pixel & 255); grey[position] = 0.299*R + 0.587*G + 0.114*B; } } return grey; } /**/ public static BufferedImage get_image_from_file (LineNumberReader file, String[] s) { BufferedImage image = null; file_functions parser = new file_functions(); s[0] = parser.get_string (file); if (s[0] == null) return null; try { image = ImageIO.read (new File(s[0])); } catch (IOException e) { System.err.println("Fail to open image: " + s); } return image; } /**/ public static void draw_rectangle (BufferedImage image, int x, int y, int w, int h) { int expand; Graphics2D gb = image.createGraphics(); Font fb = new Font("SansSerif", Font.BOLD, 14); gb.setColor(Color.black); gb.setStroke(new BasicStroke(1.0f)); gb.setFont(fb); Graphics2D gw = image.createGraphics(); Font fw = new Font("SansSerif", Font.PLAIN, 14); gw.setColor(Color.white); gw.setStroke(new BasicStroke(1.0f)); gw.setFont(fw); expand = 0; gb.drawRect(x - expand, y - expand, w + 2*expand, h + 2*expand); expand = 1; gw.drawRect(x - expand, y - expand, w + 2*expand, h + 2*expand); gb.dispose(); gw.dispose(); } public static void draw_rectangle_and_label (BufferedImage image, int x, int y, int w, int h, String label) { int expand; Graphics2D gb = image.createGraphics(); Font fb = new Font("SansSerif", Font.BOLD, 14); gb.setColor(Color.black); gb.setStroke(new BasicStroke(1.0f)); gb.setFont(fb); Graphics2D gw = image.createGraphics(); Font fw = new Font("SansSerif", Font.PLAIN, 14); gw.setColor(Color.white); gw.setStroke(new BasicStroke(1.0f)); gw.setFont(fw); expand = 0; gb.drawRect(x - expand, y - expand, w + 2*expand, h + 2*expand); expand = 1; gw.drawRect(x - expand, y - expand, w + 2*expand, h + 2*expand); Font font = new Font("Times", Font.PLAIN, 8); gb.setFont(font); gb.drawString(label, x - expand, y - expand); gb.dispose(); gw.dispose(); } public static double[] image_inversion (double image[], int width, int height) { int size = width * height; double[] out = new double[size]; /*Negating the image: [0 -> 255 and 255 -> 0]*/ for(int i = 0; i < size; i++) { out[i] = 255 - image[i]; } return out; } public static Point image_map_point_to_larger_image (Point p_r, int dscale, int redFactor, int nx, int ny) { assert(dscale >= 0); if (dscale > 0) { p_r = image_map_point_to_larger_image ( p_r, dscale-1, redFactor, (nx)/redFactor, (ny)/redFactor ); /* Centering shifts: */ int qx = ((nx%redFactor)+1)/2; int qy = ((ny%redFactor)+1)/2; /* Map {p_i} from the large image to the reduced image */ p_r.x = (int)((p_r.x - 0.5)*redFactor + qx + 0.5); p_r.y = (int)((p_r.y - 0.5)*redFactor + qy + 0.5); return p_r; } else { return p_r; } } public static Point image_map_point_to_smaller_image (Point p_i, int dscale, int redFactor, int nx, int ny) { //System.err.printf("w: %d, h: %d\n", nx, ny); assert(dscale >= 0); if (dscale > 0) { /* Centering shifts: */ int qx = ((nx%redFactor)+1)/2; int qy = ((ny%redFactor)+1)/2; /* Map {p_i} from the large image to the reduced image */ p_i.x = (int)((p_i.x - qx - 0.5)/redFactor + 0.5); p_i.y = (int)((p_i.y - qy - 0.5)/redFactor + 0.5); return image_map_point_to_smaller_image ( p_i, dscale-1, redFactor, (nx+1)/redFactor, (ny+1)/redFactor); } else { return p_i; } } public static Point image_map_point_to_smaller_image2 (Point p_i, int dscale, int redFactor, int nx, int ny) { System.err.printf("w: %d, h: %d\n", nx, ny); assert(dscale >= 0); if (dscale > 0) { /* Centering shifts: */ int qx = ((nx%redFactor)+1)/2; int qy = ((ny%redFactor)+1)/2; /* Map {p_i} from the large image to the reduced image */ p_i.x = (int)((p_i.x - qx - 0.5)/redFactor + 0.5); p_i.y = (int)((p_i.y - qy - 0.5)/redFactor + 0.5); return image_map_point_to_smaller_image ( p_i, dscale-1, redFactor, (nx+1)/redFactor, (ny+1)/redFactor); } else { return p_i; } } }