Title: Drawing Images
Course: CPS 261: Advanced Java Concepts ~ DL & MM MASTER

Drawing Images

Confession: In this course I tend to use a "loadImage" routine that you see in my "ImageStuff" class below that is short but wasteful. I construct an ImageIcon just to conveniently access it's Image class. Then I throw away the ImageIcon. Simple and short, but wasteful. For those of you who care, I offer the following direct and clean (but slightly longer) alternative method:

   private Image loadImage(String fileName) {
       Image image=null;
       try {
           image = ImageIO.read(new File(fileName));
       } catch (IOException ex) {

           System.out.println("Error reading file:"+fileName + " err="+ex);
       }
       return image;
   }


Images:

Place the above directory at the top level of your Project directory (same level as src).

Run the following program:




import java.awt.Graphics;
import java.awt.Image;

import javax.swing.ImageIcon;
import javax.swing.JFrame;


public class ImageStuff extends JFrame
{
   Image player ;
   private Image loadImage(String fileName)
        {
          return new ImageIcon(fileName).getImage();
        }

    public ImageStuff(String name)
    {
        super(name);
        setSize(1000, 1000);
        player = loadImage("player1.png");
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

    }

    public void paint(Graphics g)
    {
       super.paint(g);
       int h = getHeight();
       int w = getWidth();
       int ih = player.getHeight(null);
       int iw  = player.getWidth(null);
       System.out.println("Image width="+iw + " Image height="+ ih);


       g.drawImage(player, 20, 20, null);
       g.drawString("natural: 20,20", 20, 300);

       g.drawImage(player, 350,20, 150,200, null);
       g.drawString("scaled: 350,20,150,200", 350, 300);
       //********************************************************

       g.drawImage(player, 20, 320, 320, 570, 0, 0, 300, 250, null);
       g.drawString("natural: 20, 320, 320, 570, 0, 0, 300, 250", 20, 570);

       g.drawImage(player, 350, 320, 650, 570, 0, 0, 300, 250, null);
       g.drawString("natural: 350, 320, 650, 570, 0, 0, 300, 250", 350, 570);


       g.drawImage(player, 20, 620, 320, 870, 0, 0, 300, 250, null);
       g.drawString("natural: 20, 620, 320, 870, 0, 0, 300, 250", 20, 870);

       g.drawImage(player, 350, 620, 650, 870, 0, 0, 300, 250, null);
       g.drawString("natural: 350, 320, 650, 570, 0, 0, 300, 250", 350, 870);

    }

    public static void main(String[] args)
    {
        ImageStuff imageStuff = new ImageStuff("Image Drawing");
    } // end of main


}


Image Gymnastics


import java.awt.Graphics;
import java.awt.Image;

import javax.swing.ImageIcon;
import javax.swing.JFrame;


public class ImageStuff extends JFrame
{
   Image player ;
   private Image loadImage(String fileName)
        {
          return new ImageIcon(fileName).getImage();
        }

    public ImageStuff(String name)
    {
        super(name);
        setSize(1000, 1000);
        player = loadImage("player1.png");
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

    }

    public void paint(Graphics g)
    {
       super.paint(g);
       int h = getHeight();
       int w = getWidth();
       int ih = player.getHeight(null);
       int iw  = player.getWidth(null);
       System.out.println("Image width="+iw + " Image height="+ ih);


       g.drawImage(player, 20, 20, null);
       g.drawString("natural: 20,20", 20, 270);

       g.drawImage(player, 350,20, 150,200, null);
       g.drawString("scaled: 350,20,150,200", 320, 270);
       //********************************************************

       g.drawImage(player, 20, 280, 320, 530, 0, 0, 300, 250, null);
       g.drawString("natural: 20, 280, 320, 530, 0, 0, 300, 250", 20, 530);

       g.drawImage(player, 350, 530, 650, 280, 0, 0, 300, 250, null);
       g.drawString("v flipped: 350, 530, 650, 280, 0, 0, 300, 250", 320, 530);

       g.drawImage(player, 670, 280, 970, 405, 0, 0, 300, 125, null);
       g.drawString("crop y: 670, 280, 970, 405, 0, 0, 300, 125", 670, 530);

       //********************************************************

       g.drawImage(player, 320, 560, 20, 810, 0, 0, 300, 250, null);
       g.drawString("h flipped: 320, 560, 20, 810, 0, 0, 300, 250", 20, 810);

       g.drawImage(player, 650, 810, 350, 560, 0, 0, 300, 250, null);
       g.drawString("v,h flipped: 650, 810, 350, 560, 0, 0, 300, 250", 320, 810);

       g.drawImage(player, 670, 560, 820, 810, 0, 0, 150, 250, null);
       g.drawString("crop x: 670, 560, 820, 810, 0, 0, 150, 250", 670, 810);

    }

    public static void main(String[] args)
    {
        ImageStuff imageStuff = new ImageStuff("Image Drawing");
    } // end of main


}


Exercises

1. Create a Checkers Board and draw in the Checker Pieces.


package checkers;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;

import javax.swing.ImageIcon;
import javax.swing.JFrame;



public class Checkers extends JFrame
{
   Image redChecker, blackChecker ;
   private Image loadImage(String fileName)
        {
          return new ImageIcon(fileName).getImage();
        }

    public Checkers(String name)
    {
        super(name);
        setSize(800, 600);
        redChecker = loadImage("redChecker.png");
        blackChecker = loadImage("blackChecker.png");
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    void drawInBox(Graphics g, Image img, int x, int y, int w, int h)
    {
        int ih = img.getHeight(null);
        int iw  = img.getWidth(null);

        double scale_width = (double)w/iw;
        double scale_height = (double)h/ih;

        double scale = Math.min(scale_width, scale_height);
        int newHeight = (int)(ih*scale);
        int newWidth = (int)(iw*scale);
        int newX = x + w/2 - newWidth/2;
        int newY = y + h/2 - newHeight/2;

        g.drawImage(img, newX, newY, newWidth, newHeight, null);
    }

    public void paint(Graphics g)
    {
       super.paint(g);
       Insets insets = getInsets();
       int top = insets.top;
       int bottom = insets.bottom;
       int left = insets.left;
       int right = insets.right;

       int height = getHeight();
       int width = getWidth();

       int cell_h = (height-top-bottom)/8;
       int cell_w = (width-left-right)/8;

       int x,y;

       for (int row=0; row < 8; row++)
       {
           y = top + row*cell_h;
           for (int col=0; col < 8; col++)
           {
               x = left + col*cell_w;
               boolean greenColor = (row+col) %2 == 1;
               if (greenColor)
               {
                   g.setColor(Color.green);
               }
               else
               {
                   g.setColor(Color.white);
               }
               g.fillRect(x, y, cell_w, cell_h);
               if (greenColor)
               {
                   Image img = null;
                   if (row <= 2)
                   {
                       img = redChecker;
                   }
                   else if (row >= 5)
                   {
                       img = blackChecker;
                   }
                   if (img != null)
                       drawInBox(g, img, x, y,
                           cell_w, cell_h);
               }
           }
       }





    }

    public static void main(String[] args)
    {
        Checkers imageStuff = new Checkers("Image Drawing");
    } // end of main


}


2. Create a chess board and add the following chess pieces to it:
blackBishop.gif
blackKing.gif
blackKnight.gif
blackPawn.gif
blackQueen.gif
blackRook.gif
whiteBishop.gif
whiteKing.gif
whiteKnight.gif
whitePawn.gif
whiteQueen.gif
whiteRook.gif

Throw all of the images you see above into the top level of your project. Save them with names like: whiteQueen.gif

You can use some of the Checkers code, but it can get quite ugly pretty quickly because we have a more complicated situation than the 2 images in checkers.

See if you can use the following file productively to do the dirty work:
Result created on the video

Piece.java




import java.awt.Graphics;
import java.awt.Image;

import javax.swing.ImageIcon;

enum ColorType {black, white};
enum PieceType {Pawn, Rook, Knight, Bishop, Queen, King};


class ChessPiece
{
    private static PieceType[] pieceType= PieceType.values();
    private static ColorType[] colorType = ColorType.values();

    public static ChessPiece[][]chessPieces = new ChessPiece[colorType.length][pieceType.length];

    public static void readInImages()
    {
        for (int i=0; i < colorType.length; i++)
            for (int j=0; j < pieceType.length; j++)
                chessPieces[i][j] = new ChessPiece(i,j);
    }

    public void draw(Graphics g, int x, int y, int wSpace, int hSpace)
    {
        double scale_width= (double)wSpace/width;
        double scale_height = (double)hSpace/height;

        double scale = Math.min(scale_width, scale_height);
        int newHeight = (int)(height*scale);
        int newWidth = (int)(width*scale);
        x = x + wSpace/2 - newWidth/2;
        y = y + hSpace/2 - newHeight/2;
        g.drawImage(pieceImg, x, y, newWidth, newHeight, null);
    }

    private Image pieceImg ;
    private int width, height;
    private Image loadImage(String fileName) {
            return new ImageIcon(fileName).getImage();
        }

    private ChessPiece(int colorIndex, int pieceIndex)
    {
        String imageName =colorType[colorIndex].toString() +
                pieceType[pieceIndex].toString()+".gif";

        pieceImg = loadImage(imageName);
        width = pieceImg.getWidth(null);
        height = pieceImg.getHeight(null);
    }


}


class BoardDimensions
{
    int left,  top,  square_width, square_height;
    BoardDimensions(int left, int top, int square_width, int square_height)
    {
        this.left=left;
        this.top = top;
        this.square_width = square_width;
        this.square_height = square_height;
    }
}

class Piece
{
    int xSquare, ySquare;
    PieceType pieceType;
    ColorType color;

    public Piece (PieceType p, ColorType color, int xSquare, int ySquare)
    {
        this.pieceType=p;
        this.color = color;
        this.xSquare = xSquare;
        this.ySquare = ySquare;
    }

     public void drawInPosition(Graphics g, BoardDimensions b)
     {
         ChessPiece chessPiece = ChessPiece.chessPieces[color.ordinal()][pieceType.ordinal()];
         int x = b.left+xSquare*b.square_width ;
         int y = b.top+ySquare*b.square_height;
         chessPiece.draw(g,x,y,b.square_width,b.square_height);
     }

}




Last Updated: September 18, 2015 1:41 PM