I want to set the size of image get through json service. ???
Here is my code
public void getImage(){
try {
URL url = new URL("https://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=good%20idea%20good%20idea%20water%20jug%20water%20jug%20thirsty%20crow%20thirsty%20crow%20long%20time%20long%20time%20jug%20jug");
URLConnection connection = url.openConnection();
String line;
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((line = reader.readLine()) != null) {
builder.append(line);
}
JSONObject json = new JSONObject(builder.toString());
String imageUrl = json.getJSONObject("responseData").getJSONArray("results").getJSONObject(0).getString("url");
BufferedImage image = ImageIO.read(new URL(imageUrl));
ImageIcon img = new ImageIcon(image);
JLabel label = new JLabel("", img, JLabel.CENTER);
jPanel1.add( label, BorderLayout.CENTER );
} catch (Exception e) {
JOptionPane.showMessageDialog(null, e.getMessage(), "Failure", JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
}
}
I am showing the image in a jPanel.I want to set the size of image so it must be smaller than panel size. How could I achieve this ????
If you don't care about the quality of the result, you could use Image#getScaledInstance, but you should have a read of The Perils of Image.getScaledInstance() of first
Image scaled = image.getScaledInstance(jPanel1.getWidth(), jPanel1.getHeight(), Image.SCALE_SMOOTH);
But this won't maintain the aspect ratio of the image, to do that, you'd have to decide which dimension is more important
int width = jPanel1.getWidth();
int height = jPanel1.getHeight();
if (width < height) {
height = -1;
} else {
width = -1;
}
Image scaled = image.getScaledInstance(width, height, Image.SCALE_SMOOTH);
Have a look at Java: maintaining aspect ratio of JPanel background image for more details
Now, if you do care about the quality of the resulting image, then you need to use a different scaling approach, you could use something like a divide and conqure approach, as demonstrated in Quality of Image after resize very low -- Java or use a 3rd party library, like ImgSclr
Now, you next problem is, the size of a component is generally calculated based on the needs of it's children. In this case, that means that jPanel1 may want to use the size of the JLabel to determine how large it should be. Equally, the JLabel will use the size of the image to determine how large it should be. Which puts you in a catch 22 problem.
You could use a JScrollPane which will allow the image to occupy a large area then is available or you will need a dynamic panel which can resize the image automatically based on the available space, but you would still need to make a determination of what the "default" or "preferred" size should be
try this:
resized = Bitmap.createScaledBitmap(yourBitmap,(int)(yourBitmap.getWidth()*0.8), (int)(yourBitmap.getHeight()*0.8), true);
Related
This is the code
btnVoltar.setIcon(new ImageIcon(AdicionarRefeiĆ§Ć£o1.class.getResource("/icons/Back Icon.png")));
I want to resize it so it fits on a label, but its way too big.
You can try this codes here, but then again this post is a duplicate from stackoverflow
private ImageIcon image; // where in your case it's your class resource
Image IMG = image.getImage(); // transform it
Image newimg = IMG.getScaledInstance(200, 200, java.awt.Image.SCALE_SMOOTH); // scale it the smooth way
//Change the 200,200 to the number you prefer to resize it to
image = new ImageIcon(newimg); // transform it back
I try to draw an image from a bufferedImage into a PDF using PDFBox but fails, and I get black images and Acrobat Reader warns whith errors like "Out of memory" (but PDF is display).
I use a bufferedImage because I need to draw a JavaFX Image object (with came from call to Funciones.crearImagenDesdeTexto(), is a function which converts a text into an Image) into PDF. Rest of images works well without using bufferedimage.
PDPixelMap img = null;
BufferedImage bi;
try {
//If item has id, I try to get image with that id (image it's shows OK on PDF)
img = new PDPixelMap(documento, read(getClass().getResourceAsStream("/com/img/" + item.getId() + ".png")));
}
catch (Exception e) {
//If item has not id or fails load image, I create image on the fly (which contains item name. This not work on PDF, shows black images)
bi = new BufferedImage(alto, ancho, BufferedImage.TYPE_INT_ARGB);
bi.createGraphics().drawImage(SwingFXUtils.fromFXImage(Funciones.crearImagenDesdeTexto(item.getNombre()), null), ancho, alto, null);
img = new PDPixelMap(documento, bi);
}
finally {
contenedor.drawXObject(img, x, y, alto, ancho);
}
NOTE: crearImagenDesdeTexto() returns a JavaFX Image Object that is create on the fly (I try this function in other parts of the program and works well, function is take from other stackOverflow response).
Your code is confusing, you have three "new PDJpeg" and one of them is in a catch (which should just handle the error). And what does "read()" do? Does it pass a stream or a BufferedImage? If it is a stream, then it is wrong, because PDJpeg is for JPEGs, not for PNG.
The second one
img = new PDJpeg(documento, (getClass().getResourceAsStream("/com/img/" + Byte.toString(item.getId()) + ".png")));
is definitively wrong for the same reason: PDJPeg is not for PNG files / streams.
If you want to create an image from a PNG file / stream, use PDPixelMap.
It is possible to create a PDJpeg object from a BufferedImage, but this is recommended only if the image wasn't encoded before. Because if you would read a BufferedImage from a JPEG, and then use PDJPeg for this, you'll have a slight loss of quality as the image is decoded and encoded again (JPEG is a "lossy" compression format).
If my advice doesn't help, please upload the JPEG file and the PDF somewhere.
Also make sure that you're using the latest version, which is 1.8.7.
Update after comments:
the parameters to createGraphics.drawImage() should be 0, 0 and not width, height. The two parameters are a location, not a size.
Finally, I find a solution (thanks also to Tilman Hausherr):
private void dibujarImagen(Item i, int x, int y, int alto, int ancho) throws IOException {
PDPixelMap img = null;
try {
img = new PDPixelMap(documento, read(getClass().getResourceAsStream("/com/img/" + i.getId() + ".png")));
}
catch (IllegalArgumentException e) {
img = new PDPixelMap(documento, SwingFXUtils.fromFXImage(Funciones.crearImagenDesdeTexto(i.getNombre()),null));
}
finally {
contenedor.drawXObject(img, x, y, alto, ancho);
}
}
I'm trying to write a simple "Paint"-like JavaFX-Application.
I draw on to a JavaFX.scene.canvas, this works quite well.
Now I want to save this canvas as a ".png" image. Works, but the transparent pixels where swapped with white ones.
How do I save transparent pixels, as transparent Pixels?
Here is how I save the canvas:
private void saveFile(){
FileChooser fc = new FileChooser();
fc.setInitialDirectory(new File("res/maps"));
fc.getExtensionFilters().add(new FileChooser.ExtensionFilter("PNG","*.png"));
fc.setTitle("Save Map");
File file = fc.showSaveDialog(primaryStage);
if(file != null){
WritableImage wi = new WritableImage((int)WIDTH,(int)HEIGHT);
try { ImageIO.write(SwingFXUtils.fromFXImage(canvas.snapshot(null,wi),null),"png",file);
} catch (IOException e) {
e.printStackTrace();
}
}
}
The problem is that when you snapshot the canvas, the first argument to snapshot is null, which means that default SnapshotParameters are used. In particular, the entire destination image is first filled with the SnapshotParameter's fill value. Since the argument is null, the default fill value is null, which means that the fill value (see SnapshotParameters.setFill) is white.
To fix this, just create a SnapshotParameters object, set its fill to transparent, and use it in the call to snapshot:
SnapshotParameters sp = new SnapshotParameters();
sp.setFill(Color.TRANSPARENT);
...
ImageIO.write(SwingFXUtils.fromFXImage(canvas.snapshot(sp, wi), null), "png", file);
I'm developing an application using Java Opencv-2.4.4 and swing GUI. Problem is that I'm unable to find any solution, that shows efficient way how to print processed image (saved in Mat object) to java swing GUI. For this moment I'm using this clumsy solution:
javax.swing.JLabel outputImage;
outputImage.setIcon(new javax.swing.ImageIcon("/home/username/Output.png"));
private void sliderStateChanged(javax.swing.event.ChangeEvent evt) {
.
.
Mat canny; // Here is saved what I want to plot
String filename = "/home/username/Output.png";
Highgui.imwrite(filename, canny); // write to disk
outputImage.setIcon(new ImageIcon(ImageIO.read(new File(filename)))); //update Icon
.
.
}
When user changes some values, inputs etc ., in GUI I have to overwrite Output.png on disk and update jLabel with new image from disk.
Is there any more elegant / efficient solution to this ? Is it posible to plot or convert Mat object directly to Canvas or Image or anything that is printable as image in swing ?
Yes there is more elegant way to do it. You can concert Mat to BufferedImage type and then just Load it with swing. The code to convert it to Buffered image is:
Mat image_tmp = your image
MatOfByte matOfByte = new MatOfByte();
Highgui.imencode(".jpg", image_tmp, matOfByte);
byte[] byteArray = matOfByte.toArray();
BufferedImage bufImage = null;
try {
InputStream in = new ByteArrayInputStream(byteArray);
bufImage = ImageIO.read(in);
} catch (Exception e) {
e.printStackTrace();
}
And then you just can paint it in your GUI object:
g.drawImage(bufImage , 0, 0, null);
where g is of type Graphics
Hope this helps.
jpeg encoding is interesting, but there are a couple problems:
it is not a lossless format, you will lose image data when compressing
it takes quite a while (around 6 to 10 times longer than the suggested one below)
public Image toBufferedImage(Mat m){
int type = BufferedImage.TYPE_BYTE_GRAY;
if ( m.channels() > 1 ) {
type = BufferedImage.TYPE_3BYTE_BGR;
}
int bufferSize = m.channels()*m.cols()*m.rows();
byte [] b = new byte[bufferSize];
m.get(0,0,b); // get all the pixels
BufferedImage image = new BufferedImage(m.cols(),m.rows(), type);
final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
System.arraycopy(b, 0, targetPixels, 0, b.length);
return image;
}
This is a readymade solution for Imshow() equivalent in Java OpenCV Its simple to use. API will look like:
Imshow im = new Imshow("Title");
im.showImage(matimage);
Visit here https://github.com/master-atul/ImShow-Java-OpenCV
This is a better solution as you don't store the image into disk and read again. Hence it reduces the overhead of reading from a disk and thus is faster.
Using #andriy's anwser. I came up with this solution. I used JFrame instead of Graphics. Hope this helps.
public void imshow(Mat src){
BufferedImage bufImage = null;
try {
MatOfByte matOfByte = new MatOfByte();
Highgui.imencode(".jpg", src, matOfByte);
byte[] byteArray = matOfByte.toArray();
InputStream in = new ByteArrayInputStream(byteArray);
bufImage = ImageIO.read(in);
JFrame frame = new JFrame("Image");
frame.getContentPane().setLayout(new FlowLayout());
frame.getContentPane().add(new JLabel(new ImageIcon(bufImage)));
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
} catch (Exception e) {
e.printStackTrace();
}
}
So I have been posting all over and have yet to get a solid answer:
I have created an image resizing class, with a crop method. The cropping works great. The issue that I am having is the background color that I specify in the drawImage function of Graphics is not working correctly. It defaults to black as the background regardless of what I supply (in this case Color.WHITE).
Also, the overlaying image or top most image (comes from a file) is being inverted (I think it is) or otherwise discolored. Just so you can conceptualize this a little bit better, I am taking a jpeg and overlaying it on top of a new BufferedImage, the new buffered image's background is not being set. Here is the code below that I am working with:
public void Crop(int Height, int Width, int SourceX, int SourceY) throws Exception {
//output height and width
int OutputWidth = this.OutputImage.getWidth();
int OutputHeight = this.OutputImage.getHeight();
//create output streams
ByteArrayOutputStream MyByteArrayOutputStream = new ByteArrayOutputStream();
MemoryCacheImageOutputStream MyMemoryCacheImageOutputStream = new MemoryCacheImageOutputStream(MyByteArrayOutputStream);
//Create a new BufferedImage
BufferedImage NewImage = new BufferedImage(Width, Height, BufferedImage.TYPE_INT_RGB);
Graphics MyGraphics = NewImage.createGraphics();
MyGraphics.drawImage(this.OutputImage, -SourceX, -SourceY, OutputWidth, OutputHeight, Color.WHITE, null);
// Get Writer and set compression
Iterator MyIterator = ImageIO.getImageWritersByFormatName("png");
if (MyIterator.hasNext()) {
//get image writer
ImageWriter MyImageWriter = (ImageWriter)MyIterator.next();
//get params
ImageWriteParam MyImageWriteParam = MyImageWriter.getDefaultWriteParam();
//set outputstream
MyImageWriter.setOutput(MyMemoryCacheImageOutputStream);
//create new ioimage
IIOImage MyIIOImage = new IIOImage(NewImage, null, null);
//write new image
MyImageWriter.write(null, MyIIOImage, MyImageWriteParam);
}
//convert output stream back to inputstream
ByteArrayInputStream MyByteArrayInputStream = new ByteArrayInputStream(MyByteArrayOutputStream.toByteArray());
MemoryCacheImageInputStream MyMemoryCacheImageInputStream = new MemoryCacheImageInputStream(MyByteArrayInputStream);
//resassign as a buffered image
this.OutputImage = ImageIO.read(MyMemoryCacheImageInputStream);
}
Can you isolate whether it's the Graphics methods or the ImageIO methods that are mangling your image? It looks like you could test this by short-circuiting the entire ImageIO process and simply assigning
this.OutputImage = NewImage;
For that matter, I assume there's something gained by the ImageIO operations? As the sample is written, it appears to be (ideally) a no-op.
Also, you don't dispose your Graphics2D before you begin the ImageIO process. It often doesn't make a difference, but you don't want to assume that.
On the overlay color distortion problem, make sure your graphics context is in paint mode and not xor mode. (Graphics.setPaintMode()). Otherwise the color bits are XOR'd together.