I am new to Stack Overflow but not new to programming. I am writing a java project for my own personal use, and maybe for some friends. I create a GUI, and add some images to a collage, and then I want to save it as a JPG that will scale to print nicely on an 8 1/2 x 11 paper (landscape).
I found the following code by asaren08 on Github, which works fine but the jpg is lower resolution. I need something of print quality.
I create my collage in an ImagePanel shown in the class below, it looks nice. I save it and print it and it is low resolution. I understand that is because my screen is lower resolution than my printer. If I create it pretending my resolution is 300 DPI, then it shows up on my screen scaled to fit, and that is what it saves, which is not what I want! It is not even proportional. For example, my laptop monitor is 15 inches -ish, wide and short. My image comes out wider than it should, exactly what I see on my monitor, but I want to to come out the way I set it, not the way it shows up on my monitor. On the other hand, I need to be able to see the GUI to set up my collage...
Any suggestions?
import java.awt.*;
import javax.swing.*;
import java.io.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
public class ImagePanel extends JPanel {
/**
* Save the Panel as image with the name and the type in parameters
*
* #param name name of the file
* #param type type of the file
*/
public void saveImage(String name,String type) {
System.out.println("width of image panel ="+getWidth());
BufferedImage image = new BufferedImage(getWidth(),getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = image.createGraphics();
paint(g2);
try{
ImageIO.write(image, type, new File(name+"."+type));
} catch (Exception e) {
e.printStackTrace();
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
}
}
Update: I added my ImagePanel to a JScrollPane as suggested in the comments. That makes it hard to see where I'm at in my collage. So for now, my silly solution is to put a little thumbnail above the ImagePanel to show what the whole thing looks like and I can see from that where I'm sitting on the ImagePanel.
Related
I am new to Java and am having a problem with my JAR file loading some graphic resources. I am using IntelliJ IDEA 2021.2 (Ultimate Edition) to write my code. While in the IDE, the code work fine and the resources are loaded, but once I create the JAR file, and run it, thew graphics don't show. I should mention I do have some graphics that show, as explained below:
package com.troymarkerenterprises;
import javax.swing.*;
import java.awt.*;
import java.util.Objects;
public class ClassTopFrame extends JPanel{
public ClassTopFrame(int screenWidth, int screenHeight) {
this.setBackground(Color.BLACK);
this.setBounds(160, 0, screenWidth-160, screenHeight/2);
JLabel jl=new JLabel();
jl.setIcon(new javax.swing.ImageIcon(Objects.requireNonNull(getClass().getResource("/i_TMEA-0002-J_Logo.png"))));
this.add(jl);
}
}
This class load the image as expected. However when I try to load button images for my menu, the buttoin images do not load. Here is the class I use to create my buttons.
package com.troymarkerenterprises;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.Objects;
public class TMButton extends JButton {
Font okuda;
public TMButton(String text, String color) {
try {
okuda = Font.createFont(Font.TRUETYPE_FONT, new File("res/f_okuda.ttf")).deriveFont(16.0F);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, new File("res/f_okuda.ttf")));
} catch (IOException | FontFormatException ignored){
}
ImageIcon defaultIcon = new ImageIcon("res/b_" + color + "_default.png");
ImageIcon hoverIcon = new ImageIcon("res/b_" + color + "_selected.png");
ImageIcon disabledIcon = new ImageIcon("res/b_disabled.png");
this.setForeground(Color.BLACK);
this.setFont(okuda);
this.setText("<html><body><br><br>"+text+"</body><html>");
this.setHorizontalTextPosition(SwingConstants.CENTER);
this.setVerticalTextPosition(SwingConstants.CENTER);
this.setIcon(defaultIcon);
this.setSelectedIcon(hoverIcon);
this.setDisabledIcon(disabledIcon);
this.setMinimumSize(new Dimension(124,70));
this.setBorder(null);
this.setBorderPainted(false);
this.validate();
}
}
As I said, I am baffled as to why this is not working. I am not sure if my project structure is wrong, or if I am creating my JAR file incorrectly. To create the JAR file I am going to IntelliJ's project structure option and creating an Artifact. After I build the Artifact, I set the executable bit in my systems file explorer, and run the far file.
I would appreciate any help anyone can suggest. If I have left something out in my explanation of the problem, I have my entire app post on my GitHub page at: https://github.com/troy-marker/TMEA-0002-J.
Thanks for any assistance, Troy.
Problem is solved. Thank you to g00se for pointing out my error.
In one case, you're filling the image icons with resources, and the other you're filling them with files. You should use the former method at all times
I was trying to load the graphics two different ways, and did not realize it. Thank you for the help.
So for my 2D game I want to use an image to represent a player but when I try to use an image, it tells me that it couldn't be "instantiated". I don't know what that means:
public class PlayerOne extends Entity{
private Image img = new Image();
[...]
#Override
public void render(Graphics g){
g.drawImage( img , x, y, Color.BLUE, new ImageObserver());
}
}
I tried it in another class with BufferedImages but that somehow doesn't work.
So it can't create Objects of neither Image nor the ImageObserver. Does anyone know a fix for this error ?
You cannot instantiate an abstract class. Please see link.
Following syntax would be operational:
private Image image = new BufferedImage(200,200,BufferedImage.TYPE_INT_RGB);
Also see link for more information on BufferedImage. Additionally, here is a tutorial which ilustrates an example implementation;
You should have an image file (*.png for example ) to start with. Then use
Image img = new ImageIcon("img.png").getImage();
Since I'm new I can't post more than two links, but this is an x-post from reddit.com/r/learnprogramming, just for full disclosure.
I'll basically just be pasting what I said there to here. Thanks for your help, if you can help.
I'm writing somewhat of a graphing application. I currently only have it able to graph sin(x), but that's not the point of this question. I am not able to draw to my main panel. Here is what it currently looks like.
I had an overridden paint function in my Window.java class, which drew the sin(x) function and the axes, but when I made an inner class which extended JPanel(), it would no longer draw.
I then tried to make a separate file, but that didn't draw anything either.
What could be preventing it from drawing?
Here are all my files in question.
edit: code in question:
GraphDraw.java:
//import stuff
Public class GraphDraw extends JPanel {
SinX sinx = new SinX();
GraphPanel p = new GraphPanel();
#Override
public void paintComponent(Graphics gc) {
super.paintComponent(gc);
Graphics2D g = gc;
p.paintComponent(g);
sinx.paint(g);
}
}
And in Window.java, I initialize GraphDraw and add it to my main panel, which is underneath the buttons in the picture and above the x/y min/max labels.
GraphDraw drawer = new GraphDraw();
/*
GUI code
*/
mainPanel.add(drawer);
SinX.java
//import stuff
public class SinX extends Component {
public void paint(Graphics g) {
g.setColor(Color.red);
for(double x=-400;x<=400;x=x+0.5) {
double y = 50 * sin(x*((Math.PI)/180));
int Y = (int)y;
int X = (int)x;
g.drawLine(400+X,300-Y,400+X,300-Y);
}
}
}
First, before anything else, do the following:
Change you object from Component to JComponent
Do not ever, ever call paintComponent() or paint() on a graphics object from swing or awt, use object.repaint(); (For reasons I won't go into here, because it's long and complicated)
From there I would try calling setVisible(true); on all your objects. If you are getting this code from a tutorial, then stop and use a different tutorial. You need to learn how swing and the AWT library work before you can start making user interfaces. Nobody uses AWT anymore because Swing is much better. For reasons why, look at the following page. If you are too lazy to do that, its because it's more optimized and more powerful.
What is the difference between Swing and AWT?
I am trying to use this source code to do a morphologial closing on an image (with canny edge detected)
https://code.google.com/p/doccrop/source/browse/DocCrop/src/imageanalysis/morphology/Closing.java?r=3
I've created an instance of Closing and I've applied it on a BufferedImage and then draw it but I get a black image as a result!!
At first I had an error saying that the image must be type_byte_gray so I used this to change type but I guess it doesn't work
BufferedImage img1= ImageIO.read(new File(path));
BufferedImage imge = new BufferedImage(img1.getHeight(),img1.getWidth(),BufferedImage.TYPE_BYTE_GRAY);
You might use an image processing framework, like Marvin or ImageJ, for such purpose, as shown below.
input:
output:
source code:
import marvin.image.MarvinColorModelConverter;
import marvin.image.MarvinImage;
import marvin.io.MarvinImageIO;
import marvin.math.MarvinMath;
import static marvin.MarvinPluginCollection.*;
public class ClosingDemo {
public ClosingDemo(){
MarvinImage image = MarvinImageIO.loadImage("./res/closingIn.png");
image = MarvinColorModelConverter.rgbToBinary(image, 127);
morphologicalClosing(image.clone(), image, MarvinMath.getTrueMatrix(60, 60));
MarvinImageIO.saveImage(image, "./res/closingOut.png");
}
public static void main(String[] args) {
new ClosingDemo();
System.exit(0);
}
}
I am having some trouble with my code which is written in java. The first time after I start eclipse it launches and runs perfectly, but if I try to run it again - without making any changes - the only thing I see is an empty JFrame. Why might this happen? I have gotten quite a bit of files so to launch them all up here would be a lot to look through. Maybe you've tried something like this before? Where the program can launch sometimes? If not tell me so I can add the code.
I know that all of my classes are called since I have printed them all in my search to get the game to work.
The entire code worked until I started to put most of it in different objects in order to make it easier to look through.
package Pacman;
import java.util.Scanner;
import javax.swing.JFrame;
public class Frame extends JFrame{
public static int Width, Height;
public static void main(String[] args){
Scanner console = new Scanner(System.in);
Width = console.nextInt();
Height = console.nextInt();
new Frame();
}
public Frame(){
new JFrame();
this.setTitle("PacMan");
this.setLocation(400,300);
this.setResizable(false);
this.setVisible(true);
Screen screen = new Screen(this, Width, Height);
this.add(screen);
}
}
This is the JFrame, but I am pretty sure the problem isn't here.
If you want to see the entire codesystem it's at github: https://github.com/Lampeskaerm/SoftTek_Projekt.git
I hope you can help me
Anne-Katrine
After adding the component you should use this.setVisible(true) in the last.