I am implementing captcha feature in our project. Its basically Tapestry framework application. I am generating random alfa-numeric string and convert it to image and display it in web page.
Now what i need is, i want to add random noise like dots lines etc to make image with text unclear. How to proceed please help.
keeping the code for reference .
-- This method gives text captcha.
`
public String generateCaptcha() {
Random random = new Random();
int min = 4; // Inclusive
int max = 9; // Exclusive
int length = random.nextInt(max-min) + min;
StringBuilder captchaStringBuffer = new StringBuilder();
for (int i = 0; i < length; i++) {
int captchaNumber = Math.abs(random.nextInt()) % 60;
int charNumber = 0;
if (captchaNumber < 26) {
charNumber = 65 + captchaNumber;
}
else if (captchaNumber < 52){
charNumber = 97 + (captchaNumber - 26);
}
else {
charNumber = 48 + (captchaNumber - 52);
}
captchaStringBuffer.append((char)charNumber);
}
return captchaStringBuffer.toString();
}
`
-- This method converts generated captcha to Image with out any noise.
`
public void textToImage(String displayCode){
String text = displayCode;
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
Font font = new Font("Arial", Font.PLAIN, 48);
g2d.setFont(font);
FontMetrics fm = g2d.getFontMetrics();
int width = fm.stringWidth(text);
int height = fm.getHeight();
g2d.dispose();
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
g2d = img.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING,
RenderingHints.VALUE_DITHER_DISABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_DEFAULT);
g2d.setFont(font);
fm = g2d.getFontMetrics();
g2d.setColor(Color.BLACK);
g2d.drawString(text, 0, fm.getAscent());
g2d.dispose();
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(img, "png", baos);
byte[] res=baos.toByteArray();
setBinaryImage("data:image/png;base64,"+Base64.encode(res));
} catch (IOException e) {
}
}
`
I am newbie so please tell in clear what ever you say.
Thanks in Advance :-)
When trying to obstruct the text that is being displayed, you can use:
Dots/Circles, spread randomly over the image with varying size and color
Lines, coming from a random point on the edge of the image to another point on the edge of the image. These can also vary in color and thickness.
As far as i know, you can use g2d.drawLine(x1, y1, x2, y2) to draw a line. Since you want it to go from the edge to another point on the edge, you have to limit your random-point-generation. You can use this approach:
public Point pointOnEdge(int width, int height) {
int side = (int) (Math.random() * 3); //0=top, 1=bot, 2=left, 3=right
int x = 0;
int y = 0;
switch(side) {
case 0:
//when on top, y is at the top of the image (0) and x is something in [0, width]
y = 0;
x = (int) (Math.random() * width);
break;
case 1:
//when on bottom, y is at the bottom of the image (image height) and x is something in [0, width]
y = height;
x = (int) (Math.random() * width);
case 2:
//when on left, x is at the left side (0) of the image and y is something in [0, height]
y = (int) (Math.random() * height);
x = 0;
break;
case 3:
//when on left, x is at the left side (0) of the image and y is something in [0, height]
y = (int) (Math.random() * height);
x = width;
break;
}
return new Point(x, y);
}
If you create two Points like that, and connect them with a line, then you have a pretty simple way of obstructing your Image Partially, thus distorting it.
Now to the Circles:
public void drawCircles(Graphics2D g2d, int width, int height) {
//draw 10 of them
for(int i = 0; i < 10; i++) {
//select a random size
int x = 10 + (int) (Math.random() * 10);
//draw circle at random position with the created size
g2d.fillOval((int) (Math.random() * width), (int) (Math.random() * height), x, x);
}
}
And like that you are now able to distort your image to make it hard to read.
I hope you have enough common code understanding to know where to put these function calls. If not, I can add it if nescessary.
EDIT 1
If you want a dotted Background for your Captcha, you can use this code before rendering the String or anything else:
boolean r = false;
boolean g = false;
for(int y = 0; y < height; y++) {
r = !r;
g = r;
for(int x = 0; x < width; x++) {
g = !g;
if(g) {
g2d.setColor(Color.GRAY);
}else {
g2d.setColor(Color.WHITE);
}
g2d.drawLine(x, y, x, y);
}
}
EDIT 2
I would recommend, that you use a different font. Then you dont have to do any streching. Good fonts for that are e.g. Gigi. You could also select a font randomly by using GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames() which returns all Fonts that Java has.
Related
I am trying to draw a grid over an image using the underlaying colours of the image to fill the circles. But some pixels are not getting the correct colour.
In this case the circles are drawn white but they should not be drawn white...
See my code below:
import processing.pdf.*;
PImage img;
color background = color(255);
void setup() {
size(1038, 525);
ellipseMode(CORNER);
noStroke();
//img = loadImage("noise2.jpg");
//img = loadImage("air.png");
img = loadImage("accidents.png");
image(img, 0, 0, width, height);
visualGrid(20, 0.4, false);
}
//void draw() {
// fill(noise.get(mouseX, mouseY));
// rect(width - 100, height - 100, 100, 100);
//}
void visualGrid(int circleSize, float fillSmoothing, boolean debug) {
float halfCircle = circleSize / 2.0;
int amountX = floor(width / circleSize);
int amountY = floor(height / circleSize);
amountY += floor(amountY * 0.1);
float offsetX = (width - (amountX * circleSize + halfCircle)) / 2 + halfCircle;
float offsetY = (height - amountY * circleSize + amountY * circleSize * 0.1) / 2;
for (int x = 0; x < amountX; x++) {
for (int y = 0; y < amountY; y++) {
float styledOffsetX = (y % 2 == 0) ? offsetX - halfCircle : offsetX;
float xpos = x * circleSize + styledOffsetX;
float ypos = circleSize * 0.9 * y + offsetY;
int sectionSize = round(circleSize * fillSmoothing);
float sectionOffset = (circleSize - sectionSize) / 2;
color c = getAvgImgColor(img.get(round(xpos + sectionOffset), round(ypos + sectionOffset), sectionSize, sectionSize));
//fill(noise.get(round(xpos), round(ypos)));
if(debug) {
stroke(255, 0, 255);
strokeWeight(1);
}
fill(c);
ellipse(xpos, ypos, circleSize, circleSize);
if(debug) {
noStroke();
fill(255, 0, 255);
rect(round(xpos + sectionOffset), round(ypos + sectionOffset), sectionSize, sectionSize);
}
}
}
}
color getAvgImgColor(PImage section) {
section.loadPixels();
int avgR = 0, avgG = 0, avgB = 0;
int totalPixels = section.pixels.length;
for (int i = 0; i < totalPixels; i++) {
color pixel = section.pixels[i];
//if(pixel == background) continue;
avgR += red(pixel);
avgG += green(pixel);
avgB += blue(pixel);
}
return color(
round(avgR / totalPixels),
round(avgG / totalPixels),
round(avgB / totalPixels)
);
}
This is what i get when drawing my grid on the image in question:
As you can see in the circled area not all circles should be filled with white... This happens in more places than just the circled are just compare this image with the one below.
I will upload the original image below, so you can use it to debug.
There's a mismatch between the dimensions of your sketch (1038 x 525) and the image you're sampling (2076 x 1048) which might explain the misalignment.
If size(2076, 1048) isn't an option try resizing the image once it's loaded in setup():
...
img = loadImage("accidents.png");
img.resize(width, height);
...
Is there any way to bend a BufferedImage in Java?
I thought that if I crop the image into smaller pieces and rotate them then I would essentially bend the image, but it doesn't seem to work.
Here is the method I created:
/**
* This is a recursive method that will accept an image the point where the bending will start and the point where the bending will end, as well as the angle of bending
*
* #param original:the original image
* #param startingPoint: the point where the bending should start
* #param endingPoint: the point where the bending should end
* #param radiands: the angle
* #return the bent image
*/
public static BufferedImage getBentImage(BufferedImage original, int startingPoint, int endingPoint, double radians) {
if (startingPoint >= endingPoint)
return original;
int type = BufferedImage.TYPE_INT_ARGB;
int width = original.getWidth();
int height = original.getHeight();
BufferedImage crop = original.getSubimage(0, 0, startingPoint, height);
BufferedImage crop0 = original.getSubimage(startingPoint, 0, width - startingPoint, height);
BufferedImage bendCrop = new BufferedImage(width, height, type);
BufferedImage image = new BufferedImage(width, height, type);
AffineTransform rotation = new AffineTransform();
rotation.translate(0, 0);
rotation.rotate(radians);
Graphics2D g = bendCrop.createGraphics();
g.drawImage(crop0, rotation, null);
g.dispose();
g = image.createGraphics();
g.drawImage(crop, 0, 0, null);
g.drawImage(bendCrop, startingPoint, 0, null);
g.dispose();
return getBentImage(image, startingPoint + 1, endingPoint, radians);
}
This is the original Image:
And this is the result of this getBentImage(image, 200, 220, Math.toRadians(1)):
I was expecting something closer to:
Any ideas on how to actually implement a getBentImage() method?
As suggested in the comments, a simple approach is to divide the image into 3 parts:
Identical to the original.
Bent according to the bending transformation.
Constant diagonal continuation.
Here is a quick and a bit messy example that shows the original shape and the resulting shape below it. I just used a label icon for the images instead of doing custom painting. (Also I didn't adhere to the Java naming conventions with final variables because it's math and not typical coding.)
Since there are quite a few variables in the calculation code, I added a sketch at the end that shows what the variables represent.
public class Main extends JFrame {
static BufferedImage image;
public static void main(String[] args) {
try {
image = ImageIO.read(ClassLoader.getSystemResource("img.png"));
} catch (IOException e) {
e.printStackTrace();
}
new Main();
}
public Main() {
getContentPane().setLayout(new BorderLayout(5, 10));
BufferedImage img2 = transform(15, 100, 300);
JLabel label1 = new JLabel(new ImageIcon(image));
label1.setHorizontalAlignment(JLabel.LEFT);
label1.setOpaque(true);
label1.setBackground(Color.YELLOW);
add(label1, BorderLayout.NORTH);
JLabel label2 = new JLabel(new ImageIcon(img2));
label2.setHorizontalAlignment(JLabel.LEFT);
label2.setOpaque(true);
label2.setBackground(Color.CYAN);
add(label2);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
static BufferedImage transform(int t, int x1, int x2) {
final double TH = Math.toRadians(t);
final int D = x2 - x1;
final int W = image.getWidth();
final int H = image.getHeight();
final int dD = (int) (D / (2 * TH) * Math.sin(2 * TH));
final int dH = (int) (D / TH * Math.pow(Math.sin(TH), 2));
final int pH = (int) ((W - x2) * Math.tan(2 * TH));
final int width = W - (D - dD);
final int height = (int) (H + dH + pH);
System.out.println(W + " " + H + " -> " + width + " " + height);
BufferedImage img2 = new BufferedImage(width, height, image.getType());
for (int x = 0; x < x1; x++) {
for (int y = 0; y < H; y++) {
int rgb = image.getRGB(x, y);
img2.setRGB(x, y, rgb);
}
}
for (int x = x1; x < x2; x++) {
for (int y = 0; y < H; y++) {
int rgb = image.getRGB(x, y);
int dx = (int) (D / (2 * TH) * Math.sin(2 * (x-x1) * TH / D));
int dy = (int) (D / TH * Math.pow(Math.sin((x-x1) * TH / D), 2));
img2.setRGB(x1 + dx, y + dy, rgb);
}
}
for (int x = x2; x < W; x++) {
for (int y = 0; y < H; y++) {
int rgb = image.getRGB(x, y);
int dp = (int) ((x - x2) * Math.tan(2 * TH));
img2.setRGB(x - (D - dD), y + dH + dp, rgb);
}
}
return img2;
}
}
As for the calculations, I'll leave it for you as homework; it's just geometry/trigonometry which belongs on Math.SE more than on SO. If you can't figure it out I'll give you a direction.
Note that this method might not be fast at all and could certainly be optimized, I'll leave that to you also. Oh, and rounding doubles to ints carelessly, so the result is not pixel-perfect.
I dont know what you mean by bending but essentially you have a rectangle and you break one piece of it and rotate it:
so the algorithm is as follows:
rotate line(x, 0, width-1, 0)
rotate line(x, height-1, width-1, height-1)
connect the pieces
So essentially you are looking for rotate line.
So I have a byte array representing pixel data (8bit grayscale). No header. No nothing. Just the data. I want to create a buffered image from this data. I did
image = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);
image.getRaster().setDataElements(0, 0, w, h, data);
this.x = w;
this.y = h;
scalemode=false;
exactmode=true;
where w is just width in pixel,h is height in pixel,data is the byte array and image is BufferedImage
here is my paint method
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int rx = (this.getWidth() - x) / 2;
int ry = (this.getHeight() - y) / 2;
g2d.drawImage(image, rx, ry,x,y, null);
}
I, however, get this image (the real image is a fingerprint, which is mostly white pixel)
What went wrong? I tried saving the data as is and then viewing it in Photoshop. The data is fine.
[edit]
Never mind this problem. I fucked up in other part of the code and was not aware. Thank you for all inputs though
It's hard to know exactly what is wrong, as you haven't posted enough information. We don't know w, h or what information is in your data. We don't know what the image should look like.
However, here's some code that does pretty much exactly what you are doing, and it works for me:
// Set up h/w and backing data
int w = 300;
int h = 200;
byte[] data = new byte[w * h];
// Create a smooth gradient
for (int y = 0; y < h; y++) {
int off = y * w;
for (int x = 0; x < w; x++) {
data[off + x] = (byte) (Math.round((x / (double) w) * 127)
+ Math.round((y / (double) h) * 127));
}
}
// Create BufferedImage from data
final BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);
image.getRaster().setDataElements(0, 0, w, h, data);
// Show it all in a window
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame(getClass().getSimpleName());
frame.add(new JLabel(new ImageIcon(image)));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
Here is the result:
draw every byte on each pixel...
BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);
for (int dy = 0; dy < h; dy ++){
for(int dx = 0; dx < w; dx ++){
int index = dy*w + dx;
int rgb = data[index];
rgb = rgb << 24 & 0xFFFF; //BufferedImage.TYPE_BYTE_GRAY consideres only the red-channel;
//rgb = 00 data[index] FF FF
image.setRGB(dx,dy,rgb);
}
}
}
you didn't set up your Buffer properly...
byte[] data = ...
DataBufferByte db = new DataBufferByte(data, w*h);
image.getRaster().setDataElements(0, 0, w, h, db );
see http://docs.oracle.com/javase/7/docs/api/java/awt/image/WritableRaster.html#setDataElements%28int,%20int,%20java.lang.Object%29
I have a draw function
public void drawBoard(Graphics g) {
int height = this.getHeight();
int width = this.getWidth();
int dx = width / 7;
int dy = height / 6;
for (int x = 0, row = 0; x <= width && row < gameboard.length; row++, x += dx) {
for (int col = 0, y = 0; y <= height&& col < gameboard[0].length; y += dy, col++) {
if (gameboard[row][col] == 0) {
g.setColor(Color.GRAY);
g.fillOval(y, x, dy, dx);
} else if (gameboard[row][col] == 1) {
g.setColor(Color.RED);
g.fillOval(y, x, dy, dx);
} else if(gameboard[row][col] == 1){
g.setColor(Color.BLACK);
g.fillOval(y, x, dy, dx);
} else if(gameboard[row][col]==3){
}else if(gameboard[row][col]==4){
}else if(gameboard[row][col]==5){
}else if(gameboard[row][col]==6){
}else if(gameboard[row][col]==7){
}else if(gameboard[row][col]==8){
}else if(gameboard[row][col]==9){
}
}
}
}
However for when gameboard[row][col]=3,4,...9 I want it to change that slot into a picture downloaded from the web. How do I do that?
I would prefer to do it without a URL definition and simply a get Document like thing in html where I have the photos saved in a file
First, you need to get your image as a BufferedImage. I suggest using the ImageIO class:
String imageFileName = "myTestFile.jpg"
BufferedImage img = ImageIO.read(((new File(imageFileName)).toURI()).toURL());
Next, you want to draw your image using the Graphics.drawImage() API. Your comment indicates that you think you'll need to scale the image, so use the appropriate drawImage method to do that. Using your Graphics object g from your code above, this might look like::
int oldWidth = img.getWidth();
int oldHeight = img.getHeight();
int newWidth = 10; //You decide this...
int newHeight = 10; //You decide this too...
g.drawImage(img, 0, 0, oldWidth, newWidth, 0, 0, newWidth, newHeight, null);
Oracle themselves have an applet which demonstrates the code for this approach, along with a number of other common operations you might want to do on images in their ImageDrawingApplet.java code
I was given an assignment and have been able to complete it, but I feel there must be a easier way to complete it.
I was tasked to draw 60 vertical bars with a width of 5 and random heights.
public void paintComponent( Graphics g )
{
super.paintComponent( g );
g.setColor( color );
int width = getWidth();
int height = getHeight();
int x, h;
// bar with a width of 5 and random heights
h = rd.nextInt(height); //random height
x = 50;
g.drawLine( x, height, x, height-h ); //Bar 1
g.drawLine( x+1, height, x+1, height-h );
g.drawLine( x+2, height, x+2, height-h );
g.drawLine( x+3, height, x+3, height-h );
g.drawLine( x+4, height, x+4, height-h );
g.drawLine( x+6, height, x+6, height-h -12 ); // Bar 2
g.drawLine( x+7, height, x+7, height-h -12 );
g.drawLine( x+8, height, x+8, height-h -12 );
g.drawLine( x+9, height, x+9, height-h -12 );
g.drawLine( x+10, height, x+10, height-h -12);
What I have done is just repeat this for all 60 bars and just change the offset at the end of height-h +/- * and left a space of 1 between bars
This seems like a very long way to do this. Any suggestions on how to implement this without repeating it 60 times.
Edit: Added an image of the final project.
Here is the finished look ![1]
[1]: http://i.stack.imgur.com/3ivpM.png
Looking at the other answers, no one states the obvious:
To draw 60 bars, you don't need to draw more than 60 items (certainly not 60x5=300 lines).
Your options:
draw the bars as filled rectangles
draw the bars as lines with a width of 5
Also the bar values should not be calculated while painting, they're supposed to be the data model.
public class Bars extends JPanel {
private double[] barValues;
private final static int BAR_WIDTH = 5;
private final static int BAR_GAP = 3;
public Bars () {
barValues = new double[60];
for (int i = 0; i < barValues.length; i++) {
barValues[i] = Math.random();
}
}
...
}
Painting using rectangles:
#Override
protected void paintComponent (Graphics g) {
Dimension size = getSize();
g.setColor(Color.white);
g.fillRect(0, 0, size.width, size.height);
g.setColor(new Color(0x445566));
for (int i = 0; i < barValues.length; i++) {
int h = (int) Math.round(barValues[i] * size.height);
int x = (i * (BAR_WIDTH + BAR_GAP));
int y = size.height - 1 - h;
int w = BAR_WIDTH;
g.fillRect(x, y, w, h);
}
}
Painting using lines of width 5:
#Override
protected void paintComponent (Graphics g) {
Dimension size = getSize();
g.setColor(Color.white);
g.fillRect(0, 0, size.width, size.height);
g.setColor(new Color(0x445566));
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(5, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER));
for (int i = 0; i < barValues.length; i++) {
int h = (int) Math.round(barValues[i] * size.height);
int x = (i * (BAR_WIDTH + BAR_GAP)) + BAR_WIDTH / 2;
int y = size.height - 1 - h;
g.drawLine(x, y, x, y + h);
}
}
You could use a for loop with %
for(int i = 0, int j = 0 ; i < 360 ; i++ ) {
if(i % 5 != 0 ) {
g.drawLine( x+i, height, x+i, height-h - j);
}
if(i % 6 = 0)
j = j - 12;
}
I think that's right for what you want. I have made some assumptions:
You skip every 6th line to leave a space
You increase j by negative 12 every second line
why you don't use for loop and bunch of if statements!
for(int i = 0; i < 60; i++) {
if( i < 5) {
}
if( i > 5 && i < 10) {
}
// etc..
}
This is the second try :P
public void paintComponent(Graphics g) {
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
System.out.println("getWidth = " + getWidth());
System.out.println("getHeight = " + getHeight());
Random rd = new Random();
int x = 50;
for (int i = 0; i <= 60; i++) {
int fisrt = (i / 12) * 12;
for (int j = 0; j < 12; j++) {
int h = rd.nextInt(height); // random height
g.drawLine(x + j, height, x + j, height - h - fisrt);
}
}
}
This is a great example of when to use a loop. To draw the first five lines you need something like this.
public void drawLines(int x, int height, int h, int j){
for(int i = 0; i < 5; i++){
g.drawLine(x + i, height, x + i, height - h - j);
}
}
However, this is not complete because you have to do this multiple times. just use another for loop.
for(int i = 0; i < 12, i++){
drawLines(x + i * 5, height, h, i * 12);
}
What you saw but didn't know it
You saw a pattern of repeating code. In time and probably after an algorithm class you should be able to pre-predict patterns, some are obvious some are not. This is where reasoning, deductive and math skills come in. Which goes in the order of:
I am repeating myself...
Why am I repeating this
Is this is a basic pattern?
If I am not seeing a basic pattern...can this code be broken down further?
What is changing increase/decreasing on each same line of code
What coding idiom (loop, do-while,collection etc) do I know that best deals with this
This is also why keeping code methods short and to the point allows you to see the above more clearly.
But more important before you code: design your objects beforehand. This will allow you to solve 99 problems before you even have to deal with the coding aspect.
A good design can work in any code of that type (in this case OO/object orientated).
(Some might argue to keep the second loop in the code below to its separate method to keep it clean, readable and allow you to reuse it again.)
Your Solution
Create a method to get your barWidth and this should be your whole paintComponent method. Everything is commented and all variables are clearly defined in what they do, but if you require any help understanding any part do say.
I am not sure why you have rd as a global field.
public void paintComponent( Graphics g ) {
// Carry out super first
super.paintComponent( g );
// Set all field types at start
int totalWidth, totalHeight, barHeight, barWidth, totalBarsRequired;
// Set all constant fields
barWidth = 5; // THE BAR WIDTH IS SET HERE (Create a method)
// Set all method fields
totalWidth = getWidth();
totalHeight = getHeight();
// No need to set the bars as we can calculate them from the bar width
totalBarsRequired = (int) totalWidth / barWidth;
// Look over all the bars required
for( int barNumber = 0 ; barNumber < totalBarsRequired ; barNumber++ ) {
// Set a new random height each bar
barHeight = rd.nextInt( totalHeight );
// Create the lines and loop until the barWidth has been met
for (int barLineNumber = 0 ; barLineNumber < barWidth ; barLineNumber++ ) {
g.drawLine( (barNumber * barWidth) + barLineNumber, barHeight, (barNumber * barWidth) + barLineNumber, barHeight );
}
}
}