My GUI output is picture 1. I want to print the card in the opposite direction, as in picture 2. I use JLabel to store each card as my code shown. Any .swing or .awt method can help me do this?
CardLabel = LabelCard(cardsInHand);
int xcoordinate = 100;
for ( JLabel Label : CardLabel){
this.add(Label);
Label.setBounds(i += 20 , (int) (frame.getHeight()/5.8 * game.getCurrentIdx() +20 ) , Label.getIcon().getIconWidth(), Label.getIcon().getIconHeight() );
}
Picture 1:
Picture 2:
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
-----------------------------------------------------------------------------
public static BufferedImage FlippTheImage(BufferedImage bi) {
BufferedImage flipped = new BufferedImage(bi.getWidth(), bi.getHeight(),
bi.getType());
AffineTransform tran = AffineTransform.getTranslateInstance(0,
bi.getHeight());
AffineTransform flip = AffineTransform.getScaleInstance(1d, -1d);
tran.concatenate(flip);
Graphics2D g = flipped.createGraphics();
g.setTransform(tran);
g.drawImage(bi, 0, 0, null);
g.dispose();
return flipped;
}
in this example im using AffineTransform to flip the image you can see the doumentation for more details https://docs.oracle.com/javase/tutorial/2d/advanced/transforming.html
you can convert your icon in jlabel to bufffered image by this approach
public BufferedImage getLabelTOBufferImg(){
BufferedImage img;
int imgW, imgH,
Icon icon = lable.getIcon();
imgW = icon.getIconWidth();
imgH = icon.getIconHeight();
img = new BufferedImage(imgW, imgH, BufferedImage.TYPE_INT_ARGB);
return img;
}
Related
I am trying to do template matching in java:
This is the code:
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.awt.image.DataBufferByte;
public class pro {
public static void main(String[] args) {
try {
// RGB pixel values
byte[] pixels;
File inp=new File("TenCardG.jpg");
BufferedImage image = ImageIO.read(inp);
int width = image.getWidth();
int height = image.getHeight();
// System.out.println("Type: "+image.getColorModel());
pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.out.println("Dimension of image" + width + " "+height+" "+ " pixels length "+ pixels.length);
//rgb2gray in a 2D array grayImage
int pr;// red
int pg;// green
int pb;// blue
short [][] grayImage =new short [height][width];
int cord;
for (int i=0; i<height;i++)
for(int j=0;j<width;j++)
{
cord= 3*(i*width+j);
pr= ((short) pixels[cord] & 0xff); // red
pg= (((short) pixels[cord+1] & 0xff));// green
pb= (((short) pixels[cord+2] & 0xff));// blue
grayImage[i][j]=(short)Math.round(0.299 *pr + 0.587 * pg + 0.114 * pb);
}
Image scaledImage = image.getScaledInstance(-1,-1, 0);
ImageIO.write(
add_Rectangle(scaledImage),
"jpg",
new File("TenCardG2.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Done, check the generated TenCardG2 image at its left top corner");
}
// Add a rectangle of side size 50, 70 at coordinate 0.0 in image img
public static BufferedImage add_Rectangle(Image img) {
if (img instanceof BufferedImage) {
return (BufferedImage) img;
}
// Create a buffered image with transparency
BufferedImage bi = new BufferedImage(
img.getWidth(null), img.getHeight(null),
BufferedImage.TYPE_INT_RGB);
Graphics2D g2D = bi.createGraphics();
g2D.drawImage(img, 0, 0, null);
g2D.setColor(Color.RED);
g2D.drawRect(0, 0, 50, 70);
g2D.dispose();
return bi;
}
}
This is the source image:10 of hearts
This is the template image: Picture of heart
This a matlab code i guess which we change it to java and then implement into that code. I guess that matlab code this it compares bit by bit like and image can be compressed. if so, it will not match. its static processing. we need dynamic one. I don't know where to implement that one
When i run my code which i provide up i get this output which i get
But i should this final output
Can please try to help me
I have the original image:
I rotate the image with the following Java code:
BufferedImage bi = ImageHelper.rotateImage(bi, -imageSkewAngle);
ImageIO.write(bi, "PNG", new File("out.png"));
as the result I have the following image:
How to remove black bound around the image and make it a proper white rectangle and to not spent much space.. use only the required size for the transformation... equal to original or larger if needed?
The following program contains a method rotateImage that should be equivalent to the rotateImage method that was used in the question: It computes the bounds of the rotated image, creates a new image with the required size, and paints the original image into the center of the new one.
The method additionally receives a Color backgroundColor that determines the background color. In the example, this is set to Color.RED, to illustrate the effect.
The example also contains a method rotateImageInPlace. This method will always create an image that has the same size as the input image, and will also paint the (rotated) original image into the center of this image.
The program creates two panels, the left one showing the result of rotateImage and the right one the result of rotateImageInPlace, together with a slider that allows changing the rotation angle. So the output of this program is shown here:
(Again, Color.RED is just used for illustration. Change it to Color.WHITE for your application)
As discussed in the comments, the goal of not changing the image size may not always be achievable, depending on the contents of the image and the angle of rotation. So for certain angles, the rotated image may not fit into the resulting image. But for the use case of the question, this should be OK: The use case is that the original image already contains a rotated rectangular "region of interest". So the parts that do not appear in the output should usually be the parts of the input image that do not contain relevant information anyhow.
(Otherwise, it would be necessary to either provide more information about the structure of the input image, regarding the border size or the angle of rotation, or one would have to manually figure out the required size by examining the image, pixel by pixel, to see which pixels are black and which ones are white)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
public class RotateImageWithoutBorder
{
public static void main(String[] args) throws Exception
{
BufferedImage image =
ImageIO.read(new URL("https://i.stack.imgur.com/tMtFh.png"));
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ImagePanel imagePanel0 = new ImagePanel();
imagePanel0.setBackground(Color.BLUE);
ImagePanel imagePanel1 = new ImagePanel();
imagePanel1.setBackground(Color.BLUE);
JSlider slider = new JSlider(0, 100, 1);
slider.addChangeListener(e ->
{
double alpha = slider.getValue() / 100.0;
double angleRad = alpha * Math.PI * 2;
BufferedImage rotatedImage = rotateImage(
image, angleRad, Color.RED);
imagePanel0.setImage(rotatedImage);
BufferedImage rotatedImageInPlace = rotateImageInPlace(
image, angleRad, Color.RED);
imagePanel1.setImage(rotatedImageInPlace);
f.repaint();
});
slider.setValue(0);
f.getContentPane().add(slider, BorderLayout.SOUTH);
JPanel imagePanels = new JPanel(new GridLayout(1,2));
imagePanels.add(imagePanel0);
imagePanels.add(imagePanel1);
f.getContentPane().add(imagePanels, BorderLayout.CENTER);
f.setSize(800,500);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static BufferedImage rotateImage(
BufferedImage image, double angleRad, Color backgroundColor)
{
int w = image.getWidth();
int h = image.getHeight();
AffineTransform at = AffineTransform.getRotateInstance(
angleRad, w * 0.5, h * 0.5);
Rectangle rotatedBounds = at.createTransformedShape(
new Rectangle(0, 0, w, h)).getBounds();
BufferedImage result = new BufferedImage(
rotatedBounds.width, rotatedBounds.height,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = result.createGraphics();
g.setColor(backgroundColor);
g.fillRect(0, 0, rotatedBounds.width, rotatedBounds.height);
at.preConcatenate(AffineTransform.getTranslateInstance(
-rotatedBounds.x, -rotatedBounds.y));
g.transform(at);
g.setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(image, 0, 0, null);
g.dispose();
return result;
}
private static BufferedImage rotateImageInPlace(
BufferedImage image, double angleRad, Color backgroundColor)
{
int w = image.getWidth();
int h = image.getHeight();
AffineTransform at = AffineTransform.getRotateInstance(
angleRad, w * 0.5, h * 0.5);
Rectangle rotatedBounds = at.createTransformedShape(
new Rectangle(0, 0, w, h)).getBounds();
BufferedImage result = new BufferedImage(
w, h,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = result.createGraphics();
g.setColor(backgroundColor);
g.fillRect(0, 0, w, h);
at.preConcatenate(AffineTransform.getTranslateInstance(
-rotatedBounds.x - (rotatedBounds.width - w) * 0.5,
-rotatedBounds.y - (rotatedBounds.height - h) * 0.5));
g.transform(at);
g.setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(image, 0, 0, null);
g.dispose();
return result;
}
static class ImagePanel extends JPanel
{
private BufferedImage image;
public void setImage(BufferedImage image)
{
this.image = image;
repaint();
}
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
if (image != null)
{
g.drawImage(image, 0, 0, null);
}
}
}
}
I have some .jpg's that I'm displaying in a panel. Unfortunately they're all about 1500x1125 pixels, which is way too big for what I'm going for. Is there a programmatic way to change the resolution of these .jpg's?
You can scale an image using Graphics2D methods (from java.awt). This tutorial at mkyong.com explains it in depth.
Load it as an ImageIcon and this'll do the trick:
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
public static ImageIcon resizeImageIcon( ImageIcon imageIcon , Integer width , Integer height )
{
BufferedImage bufferedImage = new BufferedImage( width , height , BufferedImage.TRANSLUCENT );
Graphics2D graphics2D = bufferedImage.createGraphics();
graphics2D.drawImage( imageIcon.getImage() , 0 , 0 , width , height , null );
graphics2D.dispose();
return new ImageIcon( bufferedImage , imageIcon.getDescription() );
}
you can try:
private BufferedImage getScaledImage(Image srcImg, int w, int h) {
BufferedImage resizedImg = new BufferedImage(w, h, Transparency.TRANSLUCENT);
Graphics2D g2 = resizedImg.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(srcImg, 0, 0, w, h, null);
g2.dispose();
return resizedImg;
}
I'm trying to resize an image to 50 * 50 pixels. Im taking the images, from their path stored in a Database. I have no problem getting the images and displaying them. I'm just wondering at what point should I try resize the images. Should it be when I get the image as a buffered image, or just try to resize the icon?
while (rs.next()) {
i = 1;
imagePath = rs.getString("path");
System.out.println(imagePath + "\n");
System.out.println("TESTING - READING IMAGE");
System.out.println(i);
myImages[i] = ImageIO.read(new File(imagePath));
**resize(myImages[i]);**
imglab[i] = new JLabel(new ImageIcon(myImages[i]));
System.out.println(i);
imgPanel[i]= new JPanel();
imgPanel[i].add(imglab[i]);
loadcard.add(imgPanel[i], ""+i);
i++;
The above code is retrieving the image and assigning it to an ImageIcon, then JLabel. I have attempted to resize the buffered image, by using the below resize method. Could you guys, shed any light on why this isn't working for me? Not getting any errors, just the image remains its original size.
public static BufferedImage resize(BufferedImage img) {
int w = img.getWidth();
int h = img.getHeight();
int newH = 50;
int newW = 50;
BufferedImage dimg = dimg = new BufferedImage(newW, newH, img.getType());
Graphics2D g = dimg.createGraphics();
System.out.println("Is this getting here at all " + dimg);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(img, 0, 0, newW, newH, 0, 0, w, h, null);
g.dispose();
return dimg;
}
You are calling resize() on each image, but not replacing the images in the array. So the output of resize() is being thrown away:
myImages[i] = ImageIO.read(new File(imagePath)); // create an image
resize(myImages[i]); // returns resized img, but doesn't assign it to anything
imglab[i] = new JLabel(new ImageIcon(myImages[i])); // uses _original_ img
You need to change the middle line to:
myImages[i] = resize(myImages[i]);
to make this work.
I need to cut out an image in the shape of the text in another image. I think it's best shown in images.
This is a photo of a cat:
and this is the text I wish to cut out:
The resulting image would be this:
The text image will always be black with a transparent background, and the resulting cut-out should too have a transparent background. Both input images will also be the same size.
import java.awt.*;
import java.awt.font.*;
import java.awt.image.BufferedImage;
import java.awt.geom.Rectangle2D;
import javax.imageio.ImageIO;
import java.net.URL;
import java.io.File;
class PictureText {
public static void main(String[] args) throws Exception {
URL url = new URL("http://i.stack.imgur.com/Nqf3H.jpg");
BufferedImage originalImage = ImageIO.read(url);
final BufferedImage textImage = new BufferedImage(
originalImage.getWidth(),
originalImage.getHeight(),
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = textImage.createGraphics();
FontRenderContext frc = g.getFontRenderContext();
Font font = new Font(Font.SANS_SERIF, Font.BOLD, 250);
GlyphVector gv = font.createGlyphVector(frc, "Cat");
Rectangle2D box = gv.getVisualBounds();
int xOff = 25+(int)-box.getX();
int yOff = 80+(int)-box.getY();
Shape shape = gv.getOutline(xOff,yOff);
g.setClip(shape);
g.drawImage(originalImage,0,0,null);
g.setClip(null);
g.setStroke(new BasicStroke(2f));
g.setColor(Color.BLACK);
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.draw(shape);
g.dispose();
File file = new File("cat-text.png");
ImageIO.write(textImage,"png",file);
Desktop.getDesktop().open(file);
}
}
Create a new BufferedImage and iterate over all the pixels of word cat and if they are black, copy the cat-image pixels to the new image.
Here is some code: (Final working code, supports anti-alias)
public static BufferedImage textEffect(BufferedImage image, BufferedImage text) {
if (image.getWidth() != text.getWidth() ||
image.getHeight() != text.getHeight())
{
throw new IllegalArgumentException("Dimensions are not the same!");
}
BufferedImage img = new BufferedImage(image.getWidth(),
image.getHeight(),
BufferedImage.TYPE_INT_ARGB_PRE);
for (int y = 0; y < image.getHeight(); ++y) {
for (int x = 0; x < image.getWidth(); ++x) {
int textPixel = text.getRGB(x, y);
int textAlpha = (textPixel & 0xFF000000);
int sourceRGB = image.getRGB(x, y);
int newAlpha = (int) (((textAlpha >> 24) * (sourceRGB >> 24)) / 255d);
int imgPixel = (newAlpha << 24) | (sourceRGB & 0x00FFFFFF);
int rgb = imgPixel | textAlpha;
img.setRGB(x, y, rgb);
}
}
return img;
}
Use GlyphVector. Use Font class
public GlyphVector layoutGlyphVector(FontRenderContext frc,
char[] text,
int start,
int limit,
int flags) {
You can get outline Shape from glyph vector by public abstract Shape getOutline()
Assign the outline Shape as a clip to your Graphics instance.
Draw the image on the graphics.
Only clipped shape will be filled.
No java here, but the needed image operations are easy to understand. In Mathematica:
You can do it in Java with just a few lines of source code, using Marvin Framework
source code:
public class CutAndFill {
public static void main(String[] args) {
// 1. Load images
MarvinImage catImage = MarvinImageIO.loadImage("./res/catImage.jpg");
MarvinImage catText = MarvinImageIO.loadImage("./res/catText.png");
// 2. Load plug-in, set parameters and process de image
MarvinImagePlugin combine = MarvinPluginLoader.loadImagePlugin("org.marvinproject.image.combine.combineByMask");
combine.setAttribute("combinationImage", catImage);
combine.setAttribute("colorMask", Color.black);
combine.process(catText.clone(), catText);
// 3. Save the output image.
MarvinImageIO.saveImage(catText, "./res/catOut.jpg");
}
}
First, make the black portion of the "Cat" image transparent. See here for help with this. Then, composite that image over the picture of your favorite cat (mine is Sheeba).
The nice thing about this is you can make the transparent text image once, save it, and then apply it to all of Sheeba's family and friends!