import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.geom.Line2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
public class DrawingPanel extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* The width that the picture of the letter must be
*/
public static final int FIXED_WIDTH = 40;
/**
* The hight that the picture of the letter must be
*/
public static final int FIXED_HIGHT = 40;
/**
* Represents the image which is used to draw on
*/
private BufferedImage image;
public DrawingPanel() {
setBackground(Color.WHITE);
}
@Override
protected void paintComponent(Graphics g1) {
super.paintComponent(g1);
// if (image == null) {
// createDrawingArea();
// } else {
// recreateDrawingArea(image, getWidth(), getHeight());
// }
if (image == null) {
image = new BufferedImage(getWidth(), getHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = image.createGraphics();
g2.setPaint(getBackground());
g2.fillRect(0, 0, getWidth(), getHeight());
g2.dispose();
}
g1.drawImage(image, 0, 0, this);
Graphics2D graphics2 = (Graphics2D) g1;
RoundRectangle2D roundedRectangle = new RoundRectangle2D.Float(100, 100, 240, 160, 10, 10);
graphics2.draw(roundedRectangle);
}
/**
* This method is used to draw on the panel
*
* @param start
* point of the drawing line
* @param end
* point of the drawing line
*/
public void draw(Point start, Point end) {
Graphics2D g2 = image.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setPaint(Color.BLACK);
g2.setStroke(new BasicStroke(10, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_MITER));
g2.draw(new Line2D.Double(start, end));
g2.dispose();
repaint();
}
/**
* This method clears everything that is drown on the panel
*/
public void clearDrawingArea() {
Graphics g = image.getGraphics();
g.setColor(getBackground());
g.fillRect(0, 0, image.getWidth(), image.getHeight());
g.dispose();
repaint();
}
/**
* This method finds out the coordinate of the drawen letter and creates the
* approporite image from those coordinates
*/
public void getDrawnLetter() {
prepareImage();
int upperCoordinate = getUpperCoordinate();
int bottomCoordinate = getBottomCoordinate(upperCoordinate);
int leftCoordinate = getLeftCoordinate(upperCoordinate,
bottomCoordinate);
int rightCoordinate = getRightCoordinate(upperCoordinate,
bottomCoordinate, leftCoordinate);
BufferedImage subImage = image.getSubimage(leftCoordinate,
upperCoordinate, rightCoordinate - leftCoordinate,
bottomCoordinate - upperCoordinate);
// BufferedImage subImage = reSizingImage(image.getSubimage(
// leftCoordinate, upperCoordinate, rightCoordinate
// - leftCoordinate, bottomCoordinate - upperCoordinate));
// subImage = Cleaner.blackAndLightGrayCleaning(subImage);
try {
ImageIO.write(subImage, "PNG", new File("letter.png"));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void saveDrawnLetter(String letter) {
prepareImage();
int upperCoordinate = getUpperCoordinate();
int bottomCoordinate = getBottomCoordinate(upperCoordinate);
int leftCoordinate = getLeftCoordinate(upperCoordinate,
bottomCoordinate);
int rightCoordinate = getRightCoordinate(upperCoordinate,
bottomCoordinate, leftCoordinate);
BufferedImage subImage = reSizingImage(image.getSubimage(
leftCoordinate, upperCoordinate, rightCoordinate
- leftCoordinate, bottomCoordinate - upperCoordinate));
// subImage = Cleaner.blackAndLightGrayCleaning(subImage);
// int fileNumber = SaveImage.numberOfFiles(letter) + 1;
try {
ImageIO.write(subImage, "PNG", new File("1.png"));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* This method creats the image, that is used to draw on
*/
private void createDrawingArea() {
image = new BufferedImage(getWidth(), getHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics2D g = image.createGraphics();
g.setPaint(getBackground());
g.fillRect(0, 0, getWidth(), getHeight());
g.dispose();
}
/**
* This method creates new image with new demensions based on the old image
* and provided dimensions
*
* @param bufferedImage
* old image
* @param width
* new width of the image
* @param height
* new height of the image
*/
private void recreateDrawingArea(BufferedImage bufferedImage, int width,
int height) {
BufferedImage newImage = new BufferedImage(width, height,
bufferedImage.getType());
Graphics2D g = newImage.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height);
g.drawImage(bufferedImage, 0, 0, width, height, 0, 0, width, height,
null);
g.dispose();
this.image = newImage;
}
/**
* This method resizes image to the appropriate size
*
* @param bufferedImage
* represents an image that needs to be resized
*
* @return the resized image
*/
private BufferedImage reSizingImage(BufferedImage bufferedImage) {
BufferedImage newImage = new BufferedImage(FIXED_WIDTH, FIXED_HIGHT,
bufferedImage.getType());
Graphics2D g = newImage.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g.setColor(Color.WHITE);
g.fillRect(0, 0, FIXED_WIDTH, FIXED_HIGHT);
g.drawImage(bufferedImage, 0, 0, FIXED_WIDTH, FIXED_HIGHT, 0, 0,
bufferedImage.getWidth(), bufferedImage.getHeight(), null);
g.dispose();
// return ImageSampler.downSampleImage(new Dimension(FIXED_WIDTH,
// FIXED_HIGHT), newImage);
return newImage;
}
/**
* This method finds out what is the upper coordinate of the drawn letter,
* by gooing through two loops, the first starts from the 0 coordinate until
* the image height and the second starts from the 0 coordinate until the
* image widht, searching for the first pixel that has a color diffrent then
* white
*
* @return the intager value of the upper coordinate
*
* @throws RuntimeException
* if on drawing can be founded
*/
private int getUpperCoordinate() {
for (int i = 0; i < image.getHeight(); i++) {
for (int j = 0; j < image.getWidth(); j++) {
if (image.getRGB(j, i) != -1) {
return i - 1;
}
}
}
throw new RuntimeException(
"No drawing could be founded, try writing again");
}
/**
* This method finds out what is the bottom coordinate of the drawn letter,
* by gooing through two loops, the first starts from the upper coordinate
* until the image height and the second starts from the 0 coordinate until
* the image widht, searching for the first vertical line of pixels thas has
* all the white pixels
*
* @param upperCoordinate
* the upper coordinate of the drawn letter
*
* @return the intager value of the bottom coordinate
*
* @throws RuntimeException
* if on drawing can be founded
*/
private int getBottomCoordinate(int upperCoordinate) {
int counter;
for (int i = upperCoordinate + 1; i < image.getHeight(); i++) {
counter = 0;
for (int j = 0; j < image.getWidth(); j++) {
if (image.getRGB(j, i) == -1) {
counter++;
}
}
if (counter == image.getWidth()) {
return i;
}
}
throw new RuntimeException(
"No drawing could be founded, try writing again");
}
/**
* This method finds out what is the left coordinate of the drawn letter, by
* gooing through two loops, the first starts from the 0 coordinate until
* the image widht and the second starts from the upper coordinate until the
* image widht, searching for the first pixel that has a color diffrent then
* white
*
* @param upperCoordinate
* the upper coordinate of the drawn letter
* @param bottomCoordinate
* the bottom coordinate of the drawn letter
*
* @return the intager value of the left coordinate
*
* @throws RuntimeException
* if on drawing can be founded
*/
private int getLeftCoordinate(int upperCoordinate, int bottomCoordinate) {
for (int i = 0; i < image.getWidth(); i++) {
for (int j = upperCoordinate + 1; j < bottomCoordinate; j++) {
if (image.getRGB(i, j) != -1) {
return i - 1;
}
}
}
throw new RuntimeException(
"No drawing could be founded, try writing again");
}
/**
* This method finds out what is the bottom coordinate of the drawn letter,
* by gooing through two loops, the first starts from the left coordinate
* until the image widht and the second starts from the upper coordinate
* until the bottom coordinate, searching for the first horizontal line of
* pixels thas has all the white pixels
*
* @param upperCoordinate
* the upper coordinate of the drawn letter
* @param bottomCoordinate
* the bottom coordinate of the drawn letter
* @param leftCoordinate
* the left coordinate of the drawn letter
*
* @return the intager value of the right coordinate
*
* @throws RuntimeException
* if on drawing can be founded
*/
private int getRightCoordinate(int upperCoordinate, int bottomCoordinate,
int leftCoordinate) {
int counter;
for (int i = leftCoordinate + 1; i < image.getWidth(); i++) {
counter = 0;
for (int j = upperCoordinate + 1; j < bottomCoordinate; j++) {
if (image.getRGB(i, j) == -1) {
counter++;
}
}
if (counter == bottomCoordinate - upperCoordinate - 1) {
return i;
}
}
throw new RuntimeException(
"No drawing could be founded, try writing again");
}
/**
* Prepares the image for trimming by setting the white color around the
* eges in order so that coordinate of the drawen letter stay inside that
* white space
*/
private void prepareImage() {
int height = image.getHeight();
int width = image.getWidth();
for (int i = 0; i < height; i++) {
image.setRGB(0, i, -1);
image.setRGB(width - 1, i, -1);
}
for (int i = 0; i < width; i++) {
image.setRGB(i, 0, -1);
image.setRGB(i, height - 1, -1);
}
}
}