I am having some trouble displaying a dicom file. I have tried many things to display the picture onto the frame but all it does is make an error which is "image is empty". Any suggestions would be appreciated. (I know that the image is not empty and that it is able to access the image from the laptop).
Thank you.
Here is my code (which is coded in java):
class Open{
public static void main(String s) throws IOException{
String [] array = s.split("/");
String k = array[0];
k+= "/";
k += array[1];
k+= "/";
k += array[2];
k+= "/";
k+= array[3];
k+= "/";
k+= array[4];
k+= "/";
System.out.println(k);
System.out.println(s.length());
if(s.length() == 0){
System.out.println("The path and filename are empty!");
System.exit(0);
}
File source = new File(k, array[5]);
final Image image = ImageIO.read(source);
//final BufferedImage image = ImageIO.read(new File(k, array[5]));
if(image == null){
System.out.println("The image is empty or can't be read!");
System.exit(0);
}
JFrame frame = new JFrame();
final Rectangle bounds = new Rectangle(0,0,240, 240);
JPanel panel = new JPanel();
//{
// public void paintComponent(Graphics g){
//// Rectangle box = g.getClipBounds();
//// ((Graphics2D)g).fill(box);
////
//// if(bounds.intersects(box)){
// g.drawImage(image,0,0,null);
//// }
// }
// };
JLabel b = new JLabel(new ImageIcon(image));
panel.add(b);
frame.getContentPane().add(panel);
panel.setPreferredSize(new Dimension(300, 300));
frame.pack();
frame.setVisible(true);
}
}
You can do it with PixelMed. The documentation is pretty much non-existent, but there are javadocs.
If you primarily intend to display the image, you should be able to use SourceImage and SingleImagePanel from the com.pixelmed.display package to load and display the image. If you want to parse DICOM attributes, you could start with one of the read methods in com.pixelmed.dicom.AttributeList.
Related
I'm trying to show a JProgressBar in a Swing application used for communicating with a device using a SerialPort connection.
Sometimes the data that the device sends is large so it can take some time(5-10 seconds) to receive the data. Because of that, I want to show the user a progress bar so he knows that something is happening.
I tried doing this with JProgressBar and also with ProgressMonitor, but I just managed to show the progress window, but it just stayed at 0%.
Here is a method that I use to read the serialPort.
public static void readingDataSB9(SerialPort comPort) {
comPort.addDataListener(new SerialPortDataListener() {
#Override
public int getListeningEvents() {
return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
}
#Override
public void serialEvent(SerialPortEvent serialPortEvent) {
try {
if (serialPortEvent.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE) {
return;
}
//here I save the count data in the string array
List<String> countData = new ArrayList<>();
//here I save the text that is OCRed from the images
List<String> ocrText = new ArrayList<>();
//here I save the images from the machine
List<ImageIcon> serialImage = new ArrayList<>();
//trying to decode non UTF-8 strings from an array of Strings, only for TEST purposes
CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();
decoder.onMalformedInput(CodingErrorAction.IGNORE);
//Strings that represent the start of the serial number and new lines on each serial number
String startSn = "110000010011010001101100100011011000100011010000111000010001010";
String newLine = "01100000110110010001101100010001101000011100001000101";
int x = 0;
String s1 = "";
//getting InputStream from serial port and then converting it to BufferedStream, so it can be reset
//and read two times
InputStream in = comPort.getInputStream();
InputStream bufferdInputStream = new BufferedInputStream(in);
bufferdInputStream.mark(1000000000);
//I try to show progress of receiving data from InputStream
showProgress(bufferdInputStream, MainWindow.frame);
//first reading the input stream with scanner to get count data as Strings
Scanner sc = new Scanner(bufferdInputStream);
while (sc.hasNextLine()) {
countData.add(sc.next());
//this is the last string in the InputStream, so I use it to break from the while loop
if (countData.contains("\u001Bm\u001B3")) {
break;
}
}
System.out.println(countData);
//here I reset the InputStream, so it can be read again to receive the bytes needed to get the image
//of serial number
bufferdInputStream.reset();
while (((x = bufferdInputStream.read()) != 109)) {
//bytes are converted to binaryStrings, so I can get the binary image with Java Graphics library
s1 += String.format("%8s", Integer.toBinaryString(x & 0xFF)).replace(' ', '0');
}
//bytes are stored in the String array, they are split by String for the start of serial number
String[] binarySerialNumberArr = s1.split(startSn);
//here I immediately write the binaryString to the gui of MainWindow, so it can be saved to the database
MainWindow.jt_serialBinary.setText(String.join(", ", binarySerialNumberArr));
//here we take each element of String array and convert it from BinaryString to image
for (int i = 1; i < binarySerialNumberArr.length; i++) {
//first we create a empty image
BufferedImage img = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
Font font = new Font("Arial", Font.PLAIN, 2);
g2d.setFont(font);
int height = g2d.getFontMetrics().getHeight();
g2d.dispose();
//here we start to create the actual image of the serial number
img = new BufferedImage(384, 40, BufferedImage.TYPE_INT_RGB);
g2d = img.createGraphics();
g2d.setFont(font);
g2d.setColor(Color.WHITE);
int fontSize = 1;
for (String s : binarySerialNumberArr[i].split(newLine)) {
//we draw each string and use the newLine String to split the array element
//each 0 is represented as white, and 1 as black
g2d.drawString(s, 0, height);
height += fontSize;
}
//creating the image file
File file = new File("images\\Text" + i + ".png");
//saving the image to file
ImageIO.write(img, "png", file);
g2d.dispose();
//here we use the Tesseracts OCR library to get OCR text from image file
String ocrString = SerialOcr(file);
//here we fix some mistakes that OCR library does when doing OCR on images and add the data to
//OCR string array
ocrText.add(trainOcr(ocrString));
//we convert to image to ImageIcon and add it to ImageIcon array
serialImage.add(makeIcon(img));
System.out.println(ocrString);
}
//here we add ocrText to gui MainWindow
for (int i = 0; i < ocrText.size(); i++) {
MainWindow.model_ocrText.add(i, ocrText.get(i));
}
//here we add images to gui MainWindow
for (int i = 0; i < serialImage.size(); i++) {
MainWindow.model_serialImage.add(i, serialImage.get(i));
}
//here I try to ignore non UTF-8 string so I can get the OCR values from the machine also
//this is a TEST
ArrayList<String> validData = new ArrayList<>();
for (int i = 0; i < countData.size(); i++) {
decoder.decode(java.nio.ByteBuffer.wrap(countData.get(i).getBytes()));
validData.add(countData.get(i));
}
System.out.println(validData);
//checking to see what currency is the data from the machine, and building the gui table accordingly
for (int i = 0; i < countData.size(); i++) {
switch (countData.get(i)) {
case "RSD" -> insertRSD(countData, MainWindow.jt_denom);
case "USD" -> insertUSD(countData, MainWindow.jt_denom);
case "EUR" -> insertEUR(countData, MainWindow.jt_denom);
default ->
//in case none of the above currencies is chosen, we show the error message on JOptionPane
JOptionPane.showMessageDialog(null, "Odabrana valuta nije podržana", "Greška!", JOptionPane.ERROR_MESSAGE);
}
}
//after getting all the data to the gui table in MainWindow, we calculate the total count data
ButtonListeners.tableTotalAmountRows(MainWindow.jt_denom);
ButtonListeners.tableTotalAmountColumns(MainWindow.jt_denom);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
Here is the showProgress method.
public static void showProgress(InputStream bufferedInputStream, JFrame frame) throws IOException {
JOptionPane pane = new JOptionPane();
pane.setMessage("Receiving data...");
JProgressBar jProgressBar = new JProgressBar(1, bufferedInputStream.available());
jProgressBar.setValue(bufferedInputStream.read());
pane.add(jProgressBar,1);
JDialog dialog = pane.createDialog(frame, "Information message");
dialog.setVisible(true);
dialog.dispose();
}
If someone has a better idea of how to show the progress, or just to keep the message on the screen while the data is being received, please feel free to suggest it.
Thanks in advance
Can we add multiple images in Java through arrays?
Like if we want to store each picture in an array
and then display it through a loop?
And
This displays all the picture at a time. I want to display one picture then another one after some time
public static void main(String[] args) throws IOException {
String path = "C:\\Users\\MR\\Downloads\\Body Parts";
JFrame frame=new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
File folder = new File(path);
File[] listOfFiles = folder.listFiles();
DefaultListModel listModel = new DefaultListModel();
int count = 0;
for (int i = 0; i < listOfFiles.length; i++)
{
System.out.println("check path"+listOfFiles[i]);
String name = listOfFiles[i].toString();
// load only JPEGs
if ( name.endsWith("jpg") ) {
ImageIcon ii = new ImageIcon(ImageIO.read(listOfFiles[i]));
listModel.add(count++, ii);
}
}
JList lsm=new JList(listModel);
lsm.setVisibleRowCount(1);
frame.add(new JScrollPane(lsm));
frame.pack();
frame.setVisible(true);
}
Yes. Internally an array is a sequential chunk of heap memory and you can store anything /of reasonable size/.
How do I stack images (of cards) like this:
This is what I have so far and obviously I am trying to set the location of the JLabel cardIcon which gets replaced each time I guess.
JPanel tableMat = new JPanel();
for (CardSet card : playersHand) {
String path = dirPath + card.suit().toString()+"-"+card.rank().toString()+".gif";
File file = new File(path);
if (!file.exists()) {
System.out.println(path);
throw new IllegalArgumentException("file " + file + " does not exist");
} else {
BufferedImage icon = ImageIO.read(new File(file.getAbsolutePath()));
JLabel cardIcon = new JLabel(new ImageIcon(icon));
cardIcon.setLocation(300,300);
tableMat.add(cardIcon);
}
}
tableMat = new JPanel() initialises it with the default FlowLayout, so cardIcon.setLocation(300, 300) will be ignored - the layout manager will decide the position when tableMat.add(cardIcon) is called.
You need to remove the layout manager from tableMat, e.g. tableMat = new JPanel(null).
Of course, you also need to update the x co-ordinate to stagger them left-to-right.
See https://docs.oracle.com/javase/tutorial/uiswing/layout/none.html
I ended up doing like this and it works well for me.
JLayeredPane tableMat = new JLayeredPane();
int i =0;
int x_offset = 15;
for (CardSet card : playersHand) {
String path = dirPath + card.suit().toString()+"-"+card.rank().toString()+".gif";
File file = new File(path);
if (!file.exists()) {
System.out.println(path);
throw new IllegalArgumentException("file " + file + " does not exist");
} else {
BufferedImage icon = ImageIO.read(new File(file.getAbsolutePath()));
JLabel cardIcon = new JLabel(new ImageIcon(icon));
cardIcon.setBounds(x_offset,20,300,300);
tableMat.add(cardIcon, new Integer(i));
i++;
x_offset += 15;
}
}
And hence the output is :
I am trying to make a card game and Am running into an issue with my getImage() function.
I have an String Array of the Cards ex:
private static String[] hearts = {"ah.gif","2h.gif","3h.gif","4h.gif","5h.gif","6h.gif","7h.gif","8h.gif","9h.gif","th.gif","jh.gif","qh.gif","kh.gif"};
My getImage() looks like this:
public String getImage(Card card){
if (0 == suit){
img = hearts[rank];
}
else if (1 == suit){
img = spades[rank];
}
else if (2 == suit){
img = diamond[rank];
}
else if (3 == suit){
img = clubs[rank];
}
However, because it is stored as a string, I get an error when I try to use the img as an ImgIcon Ex:
ImageIcon image = (card.getImage(card));
JLabel label = new JLabel(image);
Any Ideas? Thanks
Create an array of ImageIcons and use the String array and a for loop to create the Icon array. Simple. :)
// in declaration section
private ImageIcon heartsIcons = new ImageIcon[hearts.length];
// in code section
try {
for (int i = 0; i < hearts.length; i++) {
// you may need different code to get the Image file vs. resource.
BufferedImage img = ImageIO.read(getClass().getResource(hearts[i]));
heartsIcons[i] = new ImageIcon(img);
}
} catch (IOException e) {
e.printStackTrace();
}
I am drawing a graphical representation of information my simulation is generating. I have the graph displaying but the problem i am running into is to be able to save it as a .png. When it saves the png, the file is all black, so it's not saving my graph but creating some blank png file. The problem is I am having difficulty figuring out how to cast to a BufferedImage or a RenderedImage all of my attempts in eclipse throw errors and when I get it to compile, it works as how I described above. Any thoughts or suggestions? I have been stuck on this for a couple of weeks and either it is an obvious fix or I am not able to save it as png. But from the research i have conducted, it is possible to save a java 2d graphics img as a png file, I don't know what I am missing? A fresh pair of eyes would be greatly and immensely appreciated! Thank you in advance, I appreciate any and all advice or comments regarding this.
public class GraphDisplay extends JPanel implements RenderedImage {
final int PAD = 20;
Primate p;
public GraphDisplay(){
}
public GraphDisplay(Primate p){
this.p = p;
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// now we can get x1,y1,x2,y2
double tlx= p.getMap().getX1();
double tly= p.getMap().getY1();
double brx= p.getMap().getX2();
double bry= p.getMap().getY2();
int w = getWidth();
int h= getHeight();
ArrayList <Tree> t= p.getMap().getTrees();
ArrayList<Double> xHist = p.getXHist();
ArrayList<Double> yHist = p.getYHist();
ArrayList<Double> testxHist = new ArrayList();
ArrayList<Double> testyHist = new ArrayList();
for(double i=34;i<1000;i+=5)
{
testxHist.add(i);
}
for(double i=34;i<1000;i+=5)
{
testyHist.add(i);
}
// Draw lines.
double scale=.45;
g2.setBackground(Color.WHITE);
g2.setPaint(Color.green.darker());
for(int i = 0; i < xHist.size()-1; i++) {
double x1 = PAD + (xHist.get(i)-tlx)*scale;
double y1 = (tly-yHist.get(i))*scale-PAD;
double x2 = PAD + (xHist.get(i+1)-tlx)*scale;
double y2 = (tly-yHist.get(i+1))*scale-PAD;
g2.draw(new Line2D.Double(x1, y1, x2, y2));
}
// Mark path points
if(p.getRoute()!=null)
{
ArrayList<Double> routeX= p.getRoute().getX();
ArrayList<Double> routeY= p.getRoute().getY();
g2.setPaint(Color.pink);
for(int i = 0; i < routeX.size()-1; i++) {
double x1 = PAD + (routeX.get(i)-tlx)*scale;
double y1 = (tly-routeY.get(i))*scale-PAD;
double x2 = PAD + (routeX.get(i+1)-tlx)*scale;
double y2 = (tly-routeY.get(i+1))*scale-PAD;
g2.draw(new Line2D.Double(x1, y1, x2, y2));
}
}
g2.setPaint(Color.red);
for(int i = 0; i < xHist.size(); i++) {
double x = PAD + (xHist.get(i)-tlx)*scale;
double y = (tly-yHist.get(i))*scale-PAD;
g2.fill(new Ellipse2D.Double(x-.75, y-.75, 1.5, 1.5));
}
//testing purposes
g2.setPaint(Color.BLACK);
for(int i=0;i<t.size();i++)
{
double x= PAD+(t.get(i).getX()-tlx)*scale;
double y= (tly-t.get(i).getY())*scale-PAD;
g2.fill(new Ellipse2D.Double(x-1,y-1,2,2));
}
}
public class GraphListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
saveGraph(p);
}
}
public void saveGraph(Primate p)
{
ImageIcon saveIcon = new ImageIcon("save.png");
GraphDisplay graphImg = new GraphDisplay(p);
Object graph = new GraphDisplay(p);
BufferedImage buffGraph = new BufferedImage(500,500, BufferedImage.TYPE_INT_RGB);
graph = buffGraph.createGraphics();
RenderedImage rendGraph = (RenderedImage) graphImg;
String graphFileName = JOptionPane.showInputDialog("Please enter a name for the S1Mian graphical output file: ");
File f;
f = new File(graphFileName + ".png");
//every run is unique so do not allow the user to overwrite previously saved files...
if(!f.exists())
{
try{
ImageIO.write(buffGraph, "png", f);
JOptionPane.showMessageDialog(null, graphFileName + ".png has been created and saved to your directory...", "File Saved", JOptionPane.INFORMATION_MESSAGE, saveIcon);
}
catch (IOException e)
{
e.printStackTrace();
}
}
else{
JOptionPane.showMessageDialog(null, graphFileName +".png already exists please use a different file name...", "File Exists", JOptionPane.INFORMATION_MESSAGE, saveIcon);
}
}
public void createGraph(Primate p)
{
JFrame frame = new JFrame("S1Mian Graphical Output");
//frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //disabled now that graphical output is integrated into GUI as when clicked shut down entire program...
JPanel savePanel = new JPanel();
ImageIcon saveIcon = new ImageIcon("saveIcon.png");
JButton save = new JButton("Save");
save.setToolTipText("Saves the S1Mian graphical output to a .png file");
save.setIcon(saveIcon);
GraphListener gl = new GraphListener();
save.addActionListener(gl);
GraphDisplay graph = new GraphDisplay(p);
graph.setPreferredSize(new Dimension(950, 900));
JScrollPane graphScrollPane = new JScrollPane();
graphScrollPane.setViewportView(graph);
graphScrollPane.setViewportBorder(BorderFactory.createLineBorder(Color.black));
frame.getContentPane().add(graphScrollPane, BorderLayout.CENTER);
savePanel.add(save);
frame.getContentPane().add(savePanel, BorderLayout.NORTH);
frame.setSize(900,850);
frame.setLocation(200,200);
frame.setVisible(true);
}
JPanel dPanel;
...
public void save()
{
BufferedImage bImg = new BufferedImage(dPanel.getWidth(), dPanel.getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D cg = bImg.createGraphics();
dPanel.paintAll(cg);
try {
if (ImageIO.write(bImg, "png", new File("./output_image.png")))
{
System.out.println("-- saved");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
See this example: Draw an Image and save to png.
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class WriteImageType {
static public void main(String args[]) throws Exception {
try {
int width = 200, height = 200;
// TYPE_INT_ARGB specifies the image format: 8-bit RGBA packed
// into integer pixels
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D ig2 = bi.createGraphics();
Font font = new Font("TimesRoman", Font.BOLD, 20);
ig2.setFont(font);
String message = "www.java2s.com!";
FontMetrics fontMetrics = ig2.getFontMetrics();
int stringWidth = fontMetrics.stringWidth(message);
int stringHeight = fontMetrics.getAscent();
ig2.setPaint(Color.black);
ig2.drawString(message, (width - stringWidth) / 2, height / 2 + stringHeight / 4);
ImageIO.write(bi, "PNG", new File("c:\\yourImageName.PNG"));
ImageIO.write(bi, "JPEG", new File("c:\\yourImageName.JPG"));
ImageIO.write(bi, "gif", new File("c:\\yourImageName.GIF"));
ImageIO.write(bi, "BMP", new File("c:\\yourImageName.BMP"));
} catch (IOException ie) {
ie.printStackTrace();
}
}
}
Screen Image will create a buffered image of the panel and write the image to a file.
It appears that you never actually paint to the BufferedImage in your saveGraph(..) routine.
After you create your BufferedImage and retrieve the Graphics object for that image, call the paintComponent method of your main class passing that graphics context. You also are create two GraphDisplay objects but never use either one.
GraphDisplay graphImg = new GraphDisplay(p);
//You don't need this one, you created one above named graphImg
// Object graph = new GraphDisplay(p);
BufferedImage buffGraph = new BufferedImage(500,500, BufferedImage.TYPE_INT_RGB);
//get the graphics context for the BufferedImage
Graphics2D graph = buffGraph.createGraphics();
//now tell your main class to draw the image onto the BufferedImage
graphImg.paintComponent(graph);
At this point your BufferedImage should now have the same drawing that your panel had and you should be able to save the contents.