Skip to content

Instantly share code, notes, and snippets.

@imagejan
Last active August 10, 2016 11:03
Show Gist options
  • Save imagejan/5077bae7ef626a640109c5107303c87b to your computer and use it in GitHub Desktop.
Save imagejan/5077bae7ef626a640109c5107303c87b to your computer and use it in GitHub Desktop.
import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import java.awt.geom.*;
import java.util.*;
import ij.plugin.*;
import ij.measure.*;
public class Grid2_ implements PlugIn, DialogListener {
private static double crossSize = 0.1;
private static String[] colors = {"Red","Green","Blue","Magenta","Cyan","Yellow","Orange","Black","White"};
private static String color = "Cyan";
private final static int LINES=0, HLINES=1, CROSSES=2, POINTS=3, NONE=4;
private static String[] types = {"Lines","Horizontal Lines", "Crosses", "Points", "None"};
private static String type = types[LINES];
private static double areaPerPoint;
private static boolean randomOffset, startAtTopLeft;
private static boolean bold;
private Random random = new Random(System.currentTimeMillis());
private ImagePlus imp;
private double tileWidth, tileHeight;
private int xstart, ystart;
private int linesV, linesH;
private double pixelWidth=1.0, pixelHeight=1.0;
private String units = "pixels";
public void run(String arg) {
imp = IJ.getImage();
showDialog();
}
void drawPoints() {
int one = 1;
int two = 2;
GeneralPath path = new GeneralPath();
for(int h=0; h<linesV; h++) {
for(int v=0; v<linesH; v++) {
float x = (float)(xstart+h*tileWidth);
float y = (float)(ystart+v*tileHeight);
path.moveTo(x-two, y-one); path.lineTo(x-two, y+one);
path.moveTo(x+two, y-one); path.lineTo(x+two, y+one);
path.moveTo(x-one, y-two); path.lineTo(x+one, y-two);
path.moveTo(x-one, y+two); path.lineTo(x+one, y+two);
}
}
showGrid(path);
}
void drawCrosses() {
GeneralPath path = new GeneralPath();
float arm = (int)Math.round(crossSize*tileWidth);
if (arm<3) arm=3;
for(int h=0; h<linesV; h++) {
for(int v=0; v<linesH; v++) {
float x = (float)(xstart+h*tileWidth);
float y = (float)(ystart+v*tileHeight);
path.moveTo(x-arm, y);
path.lineTo(x+arm, y);
path.moveTo(x, y-arm);
path.lineTo(x, y+arm);
}
}
showGrid(path);
}
void showGrid(Shape shape) {
if (shape==null)
imp.setOverlay(null);
else {
Roi roi = new ShapeRoi(shape);
roi.setStrokeColor(getColor());
if (bold && linesV*linesH<5000) {
ImageCanvas ic = imp.getCanvas();
double mag = ic!=null?ic.getMagnification():1.0;
double width = 2.0;
if (mag<1.0)
width = width/mag;
roi.setStrokeWidth(width);
}
imp.setOverlay(new Overlay(roi));
}
}
void drawLines() {
GeneralPath path = new GeneralPath();
int width = imp.getWidth();
int height = imp.getHeight();
for(int i=0; i<linesV; i++) {
float xoff = (float)(xstart+i*tileWidth);
path.moveTo(xoff,0f);
path.lineTo(xoff, height);
}
for(int i=0; i<linesH; i++) {
float yoff = (float)(ystart+i*tileHeight);
path.moveTo(0f, yoff);
path.lineTo(width, yoff);
}
showGrid(path);
}
void drawHorizontalLines() {
GeneralPath path = new GeneralPath();
int width = imp.getWidth();
int height = imp.getHeight();
for(int i=0; i<linesH; i++) {
float yoff = (float)(ystart+i*tileHeight);
path.moveTo(0f, yoff);
path.lineTo(width, yoff);
}
showGrid(path);
}
void showDialog() {
int width = imp.getWidth();
int height = imp.getHeight();
Calibration cal = imp.getCalibration();
int places;
if (cal.scaled()) {
pixelWidth = cal.pixelWidth;
pixelHeight = cal.pixelHeight;
units = cal.getUnits();
places = 2;
} else {
pixelWidth = 1.0;
pixelHeight = 1.0;
units = "pixels";
places = 0;
}
if (areaPerPoint==0.0)
areaPerPoint = (width*cal.pixelWidth*height*cal.pixelHeight)/81.0; // default to 9x9 grid
GenericDialog gd = new GenericDialog("Grid...");
gd.addChoice("Grid type:", types, type);
gd.addNumericField("Area per point:", areaPerPoint, places, 6, units+"^2");
gd.addChoice("Color:", colors, color);
gd.addCheckbox("Bold", bold);
gd.addCheckbox("Random offset", randomOffset);
gd.addCheckbox("Start at coordinate 0,0", startAtTopLeft);
gd.addDialogListener(this);
dialogItemChanged(gd, null);
gd.showDialog();
if (gd.wasCanceled())
showGrid(null);
}
public boolean dialogItemChanged(GenericDialog gd, AWTEvent e) {
int width = imp.getWidth();
int height = imp.getHeight();
type = gd.getNextChoice();
areaPerPoint = gd.getNextNumber();
color = gd.getNextChoice();
bold = gd.getNextBoolean();
randomOffset = gd.getNextBoolean();
startAtTopLeft = gd.getNextBoolean();
double minArea= (width*height)/50000.0;
if (type.equals(types[CROSSES])&&minArea<50.0)
minArea = 50.0;
else if (minArea<16)
minArea = 16.0;
if (areaPerPoint/(pixelWidth*pixelHeight)<minArea) {
String err = "\"Area per Point\" too small";
if (gd.wasOKed())
IJ.error("Grid", err);
else
IJ.showStatus(err);
return true;
}
double tileSize = Math.sqrt(areaPerPoint);
tileWidth = tileSize/pixelWidth;
tileHeight = tileSize/pixelHeight;
if (randomOffset) {
xstart = (int)(random.nextDouble()*tileWidth);
ystart = (int)(random.nextDouble()*tileHeight);
}
else if(startAtTopLeft){
xstart = 0;
ystart = 0;
}
else {
xstart = (int)(tileWidth/2.0+0.5);
ystart = (int)(tileHeight/2.0+0.5);
}
linesV = (int)((width-xstart)/tileWidth)+1;
linesH = (int)((height-ystart)/tileHeight)+1;
if (gd.invalidNumber())
return true;
showGrid();
return true;
}
private void showGrid() {
if (type.equals(types[LINES]))
drawLines();
else if (type.equals(types[HLINES]))
drawHorizontalLines();
else if (type.equals(types[CROSSES]))
drawCrosses();
else if (type.equals(types[POINTS]))
drawPoints();
else
showGrid(null);
}
Color getColor() {
Color c = Color.cyan;
if (color.equals(colors[0])) c = Color.red;
else if (color.equals(colors[1])) c = Color.green;
else if (color.equals(colors[2])) c = Color.blue;
else if (color.equals(colors[3])) c = Color.magenta;
else if (color.equals(colors[4])) c = Color.cyan;
else if (color.equals(colors[5])) c = Color.yellow;
else if (color.equals(colors[6])) c = Color.orange;
else if (color.equals(colors[7])) c = Color.black;
else if (color.equals(colors[8])) c = Color.white;
return c;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment