/* ******************************************************************************
* Compilation: javac-algs4 SCUtility.java
* Execution: none
* Dependencies: SeamCarver.java
*
* Some utility functions for testing SeamCarver.java.
*
**************************************************************************** */
import java.awt.Color;
import edu.princeton.cs.algs4.Picture;
import edu.princeton.cs.algs4.StdRandom;
public class SCUtility {
// create random width-by-height picture
public static Picture randomPicture(int width, int height) {
Picture picture = new Picture(width, height);
for (int col = 0; col < width; col++) {
for (int row = 0; row < height; row++) {
int r = StdRandom.uniform(256);
int g = StdRandom.uniform(256);
int b = StdRandom.uniform(256);
Color color = new Color(r, g, b);
picture.set(col, row, color);
}
}
return picture;
}
// convert SeamCarver picture to width-by-height energy matrix
public static double[][] toEnergyMatrix(SeamCarver sc) {
double[][] a = new double[sc.width()][sc.height()];
for (int col = 0; col < sc.width(); col++)
for (int row = 0; row < sc.height(); row++)
a[col][row] = sc.energy(col, row);
return a;
}
// displays grayscale values as energy (converts to picture, calls show)
public static void showEnergy(SeamCarver sc) {
doubleToPicture(toEnergyMatrix(sc)).show();
}
// returns picture of energy matrix associated with SeamCarver picture
public static Picture toEnergyPicture(SeamCarver sc) {
double[][] energyMatrix = toEnergyMatrix(sc);
return doubleToPicture(energyMatrix);
}
// converts a double matrix of values into a normalized picture
// values are normalized by the maximum grayscale value
public static Picture doubleToPicture(double[][] grayValues) {
// each 1D array in the matrix represents a single column, so number
// of 1D arrays is the width, and length of each array is the height
int width = grayValues.length;
int height = grayValues[0].length;
Picture picture = new Picture(width, height);
double maxVal = 0;
for (int col = 0; col < width; col++) {
for (int row = 0; row < height; row++) {
if (grayValues[col][row] > maxVal) {
maxVal = grayValues[col][row];
}
}
}
// return a black picture
if (maxVal == 0) {
return picture;
}
// normalize grayscale values
for (int col = 0; col < width; col++) {
for (int row = 0; row < height; row++) {
float normalized = (float) (grayValues[col][row] / (float) maxVal);
Color gray = new Color(normalized, normalized, normalized);
picture.set(col, row, gray);
}
}
return picture;
}
// This method is useful for debugging seams. It overlays red
// pixels over the calculate seam.
public static Picture seamOverlay(Picture picture, boolean isHorizontal, int[] seam) {
Picture overlaid = new Picture(picture);
// if horizontal seam, set one pixel in every column
if (isHorizontal) {
for (int col = 0; col < picture.width(); col++)
overlaid.set(col, seam[col], Color.RED);
}
// if vertical seam, set one pixel in each row
else {
for (int row = 0; row < picture.height(); row++)
overlaid.set(seam[row], row, Color.RED);
}
return overlaid;
}
}