I'm trying to draw pixels on a Canvas using a BufferedImage. In my Canvas constructor I am initializing the image and pixel array like so:
public MyCanvas() {
Dimension size = new Dimension(WIDTH, HEIGHT);
setSize(size);
setPreferredSize(size);
setMinimumSize(size);
setMaximumSize(size);
image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
pixels = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
}
I draw every render by doing:
private void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
for (int i = 0; i < pixels.length; i++) {
pixels[i] = 0xFFFFFF;
}
Graphics g = bs.getDrawGraphics();
g.fillRect(0, 0, getWidth(), getHeight());
g.drawImage(img, 0, 0, WIDTH, HEIGHT, null);
g.dispose();
bs.show();
}
I'm expecting that my canvas is filled with white pixels, but I get black borders on the right and bottom of the white area, i.e. it's doesn't seem to be filling my entire canvas, or it has some negative offset. I've checked that the length of the pixel array is WIDTH * HEIGHT. I'm putting the canvas into a JPanel with BorderLayout.CENTER, in a JFrame.
EDIT:
Changing
g.drawImage(img, 0, 0, WIDTH, HEIGHT, null);
to
g.drawImage(img, 0, 0, getWidth(), getHeight(), null);
makes it do what I expect. However I don't understand why I have to fetch the canvas size when I have set the size myself (to WIDTH, HEIGHT), and it doesn't seem to be the same as the size I gave it.
I don't see where you're setting the color for the rectangle fill.
Try this:
Graphics g = bs.getDrawGraphics();
// g.setColor(Color.WHITE);
// g.fillRect(0, 0, getWidth(), getHeight());
g.drawImage(img, 0, 0, getWidth(), getHeight(), null);
g.dispose();
bs.show();
Related
i want to add additional space in images, lets call it "span".
My code is:
BufferedImage newImage = new BufferedImage(image2.getWidth(), image2.getHeight()+200, image2.getType());
Graphics g = newImage.getGraphics();
g.setColor(Color.white);
g.fillRect(0,0,image.getWidth(),image.getHeight()+100);
g.drawImage(image, 0, 100, null);
g.setColor(Color.white);
g.dispose();
RenderedImage rendImage = newImage;
String newUrl8006002 = splitUrl[0]+"-800x6002.jpg";
File file = new File(newUrl8006002);
ImageIO.write(rendImage, "jpg", file);
The problem is, that image at the bottom has black background and i expect white (at the top is white).
Do you know what to change to add white background in whole image?
How about this:
static BufferedImage growY(BufferedImage im, int span, Color color)
{
BufferedImage newImage = new BufferedImage(im.getWidth(), im.getHeight()+span, im.getType());
int topSpan = span/2;
int botSpan = span - topSpan;
Graphics g = newImage.getGraphics();
g.setColor(color);
g.fillRect(0, 0, newImage.getWidth(), topSpan);
g.fillRect(0, topSpan+im.getHeight(), newImage.getWidth(), botSpan);
g.drawImage(im, 0, topSpan, null);
g.dispose();
return newImage;
}
I try to scale image to 50x50 px, but I got black color. I need to make black to white
after scaled
this my code:
BufferedImage imgs = urlToBufferImage("src//imgTest.jpg");
BufferedImage resizedImage = new BufferedImage(50, 50, imgs.getType());
Graphics2D g = resizedImage.createGraphics();
// g.setBackground(Color.WHITE);
// g.drawImage(imgs, 0, 0, 50, 50,Color.WHITE, null);
g.drawImage(imgs.getScaledInstance(50, -1, Image.SCALE_DEFAULT), 0, 0, this);
g.dispose();
This is pretty simple.
My approach would be not to create a new BufferedImage, but to do:
BufferedImage imgs = urlToBufferImage("src//imgTest.jpg");
Graphics g = imgs.createGraphics();
g.drawImage(imgs, x, y, 50, 50, null);
or instead of drawing the image inside of the bounds, you could do
Graphics2D g2d = imgs.createGraphics();
g2d.scale(0.5, 0.5);
g2d.drawImage(imgs, x, y, null);
Is there anyway to find the current position of a buffered image on jpanel?
I draw an image on buffer, named it currentImage. Now I want to move it around a Panel by using affine transform.
To do translation by using mouse, I have to know the current position, new position and update the new position.
But I have trouble in getting the current position of the BufferedImage. There is no method in the IDE's suggestion working.
Can anyone give me an idea how to do this ?? Thanks!
EDIT
this is my draw and paintComponent method:
private void draw(){
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC);
int w = this.getWidth(); int h = this.getHeight();
if (currentImage == null || width != w || height != h){
width = w;
height = h;
currentImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
graphics = currentImage.createGraphics();
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
drawClearAndGradedArea(graphics);
drawActualRunway(graphics, width, height, width, height);
drawLeftToRight(graphics);
drawRightToLeft(graphics);
drawCentralLine(graphics);
graphics.setComposite(ac);
}
}
paintComponent()
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.clearRect(0,0, this.getWidth(), this.getHeight());
RenderingHints rh = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHints(rh);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
/*
* main components on panel
*/
this.draw();
this.animation();
g2d.drawImage(currentImage, transform, this);
drawNote(g2d);
g2d.dispose();
}
I am trying to write a string into a image using ImageIo. But while writing a large string ,full string is not written into that image.
Here's my code:
File url=new File(imgUrl);
BufferedImage image = ImageIO.read(url);
Graphics g = image.getGraphics();
g.setPaintMode();
g.setFont(g.getFont().deriveFont(30f));
g.drawString(text, 100, 100);
g.dispose();
This code works fine for small strings.but when the width of the string exceeds the width of the image,then full string is not displayed on that image.
Any suggestions?
i have an old method try it
public BufferedImage stringToImage(String text, Font font, Color bgColor, Color fgColor) {
BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = (Graphics2D) image.getGraphics();
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
FontRenderContext fc = g2d.getFontRenderContext();
Rectangle2D bounds = font.getStringBounds(text, fc);
//calculate the size of the text
int width = (int) bounds.getWidth();
int height = (int) bounds.getHeight();
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
g2d = (Graphics2D) image.getGraphics();
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setFont(font);
g2d.setColor(bgColor);
g2d.fillRect(0, 0, width, height);
g2d.setColor(fgColor);
g2d.drawString(text, 0, (int)-bounds.getY());
g2d.dispose();
return image;
}
and use
BufferedImage image = stringToImage(text, font, bgColor, fgColor);
ImageIO.write(image, "jpg", file);
Not tested, but it could be done as this:
JLabel label = new JLabel("<html><h2>Title</h2><p>large text ...</p>");
int w = image.getWidth();
int h = image.getHeigth();
label.setBounds(0, 0, w, h);
SwingUtilities.paintComponent(g, label, null, 0, 0, w, h);
There are many ways to acheive this.
FontRenderContext/GlyphVector as mentioned by pbaris. See this answer for an e.g.
FontMetrics as seen in this answer.
A JLabel (possibly multi-line) to contain and size the text. As mentioned by Joop E.G. LabelRenderTest
You can use JTextArea to layout text:
JTextArea textArea = new JTextArea(text);
textArea.setFont(g.getFont().deriveFont(30f));
textArea.setOpaque(false);
textArea.setWrapStyleWord(true);
textArea.setLineWrap(true);
textArea.setBounds(0, 0, image.getWidth(), image.getHeight());
textArea.paint(g);
I've got a full-screen JFrame and I'd like to create an background for it by filling a JLabel with an image and matching it's size to the dimension of the screen.
Whilst I can create a JLabel that matches the screen's size I can't seem to resize my image to fit. In essence, I want to end up with a full-screen JFrame that is completely filled with an image (regardless of the image's or the screen's dimensions).
Current code is below, thanks!
public void addBackground(ImageIcon imgIcon) {
Image img = imgIcon.getImage();
BufferedImage buffImg = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
BufferedImage resizeBuffImg = resize(buffImg, screenSize.width, screenSize.height);
Image finalImg = Toolkit.getDefaultToolkit().createImage(resizeBuffImg.getSource());
ImageIcon back = new ImageIcon(finalImg);
System.out.println("IMAGE WIDTH: " + back.getIconWidth());
System.out.println("IMAGE HEIGHT: " + back.getIconHeight());
JLabel backgroundLabel = new JLabel(back);
getContentPane().add(backgroundLabel);
}
public BufferedImage resize(BufferedImage image, int width, int height) {
int type = image.getType() == 0? BufferedImage.TYPE_INT_ARGB : image.getType();
BufferedImage resizedImage = new BufferedImage(width, height, type);
Graphics2D g = resizedImage.createGraphics();
g.setComposite(AlphaComposite.Src);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.drawImage(image, 0, 0, width, height, null);
g.dispose();
return resizedImage;
}
EDIT - Got it! Using Image's getScaledInstance() works. It's not perfect, but I'm intending to scale down large images rather than expand smaller ones.