Image IO Write not writing - java

basically I am trying to save an image I have edited in a JFrame, so I have a menu with the save item and I have an action listener to set up for the save item and everything works fine, the file chooser comes up and I can select where I would like to save it, only thing is when I hit save, its not there. Here is my code, am I missing something?
if(e.getSource().equals(Save)){
JFileChooser keep = new JFileChooser();
keep.setSelectedFile(new File ("newImage.jpg"));
FileNameExtensionFilter filters = new FileNameExtensionFilter("jpeg", "jpg");
keep.setFileFilter(filters);
File output = keep.getSelectedFile();
int count = keep.showSaveDialog(keep);
BufferedImage out = filteredImage;
if (count == JFileChooser.CANCEL_OPTION){
}
else{
try{
ImageIO.write(out, "jpg", output);
//I put this here to see if I was even reaching the method
System.out.println("writing method");
}catch(Exception d){
}
}
}

So, you get a reference to the selectedFile...
File output = keep.getSelectedFile();
The you show the dialog...
int count = keep.showSaveDialog(keep);
BufferedImage out = filteredImage;
Then you try and save the image...
ImageIO.write(out, "jpg", output);
...wait, what?! Assuming that getSelectedFile isn't null, how do you know where you're actually saving the image?
That process should be reversed slightly...
showSaveDialog
if (accepted) {
saveFile = getSelectedFile
ImageIO.write(img, "jpg", saveFile);
}
as a basic psudo code example

Related

Loading pictures from Filechooser

My code:
try {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("Open Resource File");
fileChooser.getExtensionFilters().add(new FileChooser.ExtensionFilter("PNG", "*.png"));
File file = fileChooser.showOpenDialog(null);
BufferedImage originalImage = ImageIO.read(new File(memberView.selectedPicturePath.getText()));
ImageIO.write(originalImage, ".png", file.getAbsoluteFile());
} catch (IOException e) {
System.out.println(e.getMessage());
}
i want to save an image from a random directory to the one specified here but every time i get a Can't read input file! message.
The image i am trying to load actually exists since i am choosing it with the file loader.
Where is the problem in this code?
Check that what method memberView.selectedPicturePath.getText()) is return, perhaps it is not valid path to your image.

javafx read javafx.scene.image.Image to ImageIO.write(), from CMYK to RGB

What I want to do is read an image from FileChooser and write it to file. I had to store the image in a javafx.scene.image.Image so that I can display it and clip it inside a circle. I have a little problem with trying to write the image that I got from javafx.scene.image.Image to file. The conversion process is not fluid, converts from CMYK to RGB (therefore turning my picture to some pink thing.
Please, I have checked a lot of other sources, and no one has been able to give me a notable solution
FileChooser fileChooser = new FileChooser();
File selectedFile = fileChooser.showOpenDialog(parent);
// get Image from selectedFile
Image userImg = = new Image( selectedFile.toURI().toURL().toString() );
if ( userImg != null ) {
String format = "jpg";
String filename = "d:\\pictureName."+ format;
File file = new File(filename);
// convert Image to BufferedImage
BufferedImage bufferedImage = SwingFXUtils.fromFXImage( userImg, null);
try {
// this is where i want to convert the color mode
// from cmyk to rgb, before i write it to file
ImageIO.write( bufferedImage, format, file );
} catch (IOException e) {
System.out.println("Exception :: "+ e.getMessage() );
}
}
Why do you think that there is some CMYK to RGB conversion happening? I suspect the reason for your "pink thing" is something different. The easiest way to find out is to change your output format from jpeg to png and see whether it makes a difference.
I think you are again one of the many people who are hit by this bug https://bugs.openjdk.java.net/browse/JDK-8119048 which is not considered important enough to be fixed. If you read the comments in there you will find a work-arround. Basically the idea is to copy the image after the conversion into a new image without alpha channel.
I'd really like to know how many more people have to waste their time until this bug finally gets enough attention to be fixed.

Save image inside specific folder and store path in mysql to display later

For my project, I am creating an expense management system. There is a place where the user can select an image file from local disk and add it as an attachment when adding a new expense.
The uploaded image should be displayed in a jLabel and then should be saved inside the project folder (say for e.g. /src/accounts/media) when clicking the save button, and the path should be saved inside a varchar column in mysql database for later retrieval.
For now, I can upload the image and display the image in jLabel.
Can anyone help me out on how save that image file inside a folder and to store the path in database?
JFileChooser chooser = new JFileChooser();
FileFilter ft = new FileNameExtensionFilter("Image Files", "jpg", "png", "jpeg");
//FileFilter ft2 = new FileNameExtensionFilter("PDF Files", "pdf");
chooser.addChoosableFileFilter(ft);
//chooser.addChoosableFileFilter(ft2);
chooser.showOpenDialog(null);
File f = chooser.getSelectedFile();
filePath = f.getAbsolutePath().toString();
BufferedImage img = null;
try {
img = ImageIO.read(new File(filePath));
} catch (IOException e) {
e.printStackTrace();
}
Image dimg = img.getScaledInstance(lblAttachment.getWidth(), lblAttachment.getHeight(), Image.SCALE_SMOOTH);
ImageIcon icon = new ImageIcon(dimg);
lblAttachment.setText("");
lblAttachment.setIcon(icon);
To copy file to another location, you can choose any
Way1
Way2
To store the path, make a file-path column write insert query (SQL) :
prepareStatement ps = conn.prepareStatement("INSERT INTO filePath VALUES(?, ?, ?)" );
ps.setString(1,filePath);
ps.set..
// conn, connection object
Full tutorial Here
Edit:
To save it in you some default Resources folder, You can obtain path, for EG:
public class ClassDemo {
public static void main(String[] args) throws Exception {
ClassDemo c = new ClassDemo();
Class cls = c.getClass();
// finds resource relative to the class location
URL url = cls.getResource("file.txt");
System.out.println("Value = " + url);
// finds resource relative to the class location
url = cls.getResource("newfolder/a.txt");
System.out.println("Value = " + url);
}
}

How do you access an attachment stored as MIME Part?

It seems to me there are two ways to store an attachment in a NotesDocument.
Either as a RichTextField or as a "MIME Part".
If they are stored as RichText you can do stuff like:
document.getAttachment(fileName)
That does not seem to work for an attachment stored as a MIME Part. See screenshot
I have thousands of documents like this in the backend. This is NOT a UI issue where I need to use the file Download control of XPages.
Each document as only 1 attachment. An Image. A JPG file. I have 3 databases for different sizes. Original, Large, and Small. Originally I created everything from documents that had the attachment stored as RichText. But my code saved them as MIME Part. that's just what it did. Not really my intent.
What happened is I lost some of my "Small" pictures so I need to rebuild them from the Original pictures that are now stored as MIME Part. So my ultimate goal is to get it from the NotesDocument into a Java Buffered Image.
I think I have the code to do what I want but I just "simply" can't figure out how to get the attachment off the document and then into a Java Buffered Image.
Below is some rough code I'm working with. My goal is to pass in the document with the original picture. I already have the fileName because I stored that out in metaData. But I don't know how to get that from the document itself. And I'm passing in "Small" to create the Small image.
I think I just don't know how to work with attachments stored in this manner.
Any ideas/advice would be appreciated! Thanks!!!
public Document processImage(Document inputDoc, String fileName, String size) throws IOException {
// fileName is the name of the attachment on the document
// The goal is to return a NEW BLANK document with the image on it
// The Calling code can then deal with keys and meta data.
// size is "Original", "Large" or "Small"
System.out.println("Processing Image, Size = " + size);
//System.out.println("Filename = " + fileName);
boolean result = false;
Session session = Factory.getSession();
Database db = session.getCurrentDatabase();
session.setConvertMime(true);
BufferedImage img;
BufferedImage convertedImage = null; // the output image
EmbeddedObject image = null;
InputStream imageStream = null;
int currentSize = 0;
int newWidth = 0;
String currentName = "";
try {
// Get the Embedded Object
image = inputDoc.getAttachment(fileName);
System.out.println("Input Form : " + inputDoc.getItemValueString("form"));
if (null == image) {
System.out.println("ALERT - IMAGE IS NULL");
}
currentSize = image.getFileSize();
currentName = image.getName();
// Get a Stream of the Imahe
imageStream = image.getInputStream();
img = ImageIO.read(imageStream); // this is the buffered image we'll work with
imageStream.close();
Document newDoc = db.createDocument();
// Remember this is a BLANK document. The calling code needs to set the form
if ("original".equalsIgnoreCase(size)) {
this.attachImage(newDoc, img, fileName, "JPG");
return newDoc;
}
if ("Large".equalsIgnoreCase(size)) {
// Now we need to convert the LARGE image
// We're assuming FIXED HEIGHT of 600px
newWidth = this.getNewWidth(img.getHeight(), img.getWidth(), 600);
convertedImage = this.getScaledInstance(img, newWidth, 600, false);
this.attachImage(newDoc, img, fileName, "JPG");
return newDoc;
}
if ("Small".equalsIgnoreCase(size)) {
System.out.println("converting Small");
newWidth = this.getNewWidth(img.getHeight(), img.getWidth(), 240);
convertedImage = this.getScaledInstance(img, newWidth, 240, false);
this.attachImage(newDoc, img, fileName, "JPG");
System.out.println("End Converting Small");
return newDoc;
}
return newDoc;
} catch (Exception e) {
// HANDLE EXCEPTION HERE
// SAMLPLE WRITE TO LOG.NSF
System.out.println("****************");
System.out.println("EXCEPTION IN processImage()");
System.out.println("****************");
System.out.println("picName: " + fileName);
e.printStackTrace();
return null;
} finally {
if (null != imageStream) {
imageStream.close();
}
if (null != image) {
LibraryUtils.incinerate(image);
}
}
}
I believe it will be some variation of the following code snippet. You might have to change which mimeentity has the content so it might be in the parent or another child depending.
Stream stream = session.createStream();
doc.getMIMEEntity().getFirstChildEntity().getContentAsBytes(stream);
ByteArrayInputStream bais = new ByteArrayInputStream(stream.read());
return ImageIO.read(bais);
EDIT:
session.setConvertMime(false);
Stream stream = session.createStream();
Item itm = doc.getFirstItem("ParentEntity");
MIMEEntity me = itm.getMIMEEntity();
MIMEEntity childEntity = me.getFirstChildEntity();
childEntity.getContentAsBytes(stream);
ByteArrayOutputStream bo = new ByteArrayOutputStream();
stream.getContents(bo);
byte[] mybytearray = bo.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(mybytearray);
return ImageIO.read(bais);
David have a look at DominoDocument,http://public.dhe.ibm.com/software/dw/lotus/Domino-Designer/JavaDocs/XPagesExtAPI/8.5.2/com/ibm/xsp/model/domino/wrapped/DominoDocument.html
There you can wrap every Notes document
In the DominoDocument, there such as DominoDocument.AttachmentValueHolder where you can access the attachments.
I have explained it at Engage. It very powerful
http://www.slideshare.net/flinden68/engage-use-notes-objects-in-memory-and-other-useful-java-tips-for-x-pages-development

Can I tell what the file type of a BufferedImage originally was?

In my code, I have a BufferedImage that was loaded with the ImageIO class like so:
BufferedImage image = ImageIO.read(new File (filePath);
Later on, I want to save it to a byte array, but the ImageIO.write method requires me to pick either a GIF, PNG, or JPG format to write my image as (as described in the tutorial here).
I want to pick the same file type as the original image. If the image was originally a GIF, I don't want the extra overhead of saving it as a PNG. But if the image was originally a PNG, I don't want to lose translucency and such by saving it as a JPG or GIF. Is there a way that I can determine from the BufferedImage what the original file format was?
I'm aware that I could simply parse the file path when I load the image to find the extension and just save it for later, but I'd ideally like a way to do it straight from the BufferedImage.
As #JarrodRoberson says, the BufferedImage has no "format" (i.e. no file format, it does have one of several pixel formats, or pixel "layouts"). I don't know Apache Tika, but I guess his solution would also work.
However, if you prefer using only ImageIO and not adding new dependencies to your project, you could write something like:
ImageInputStream input = ImageIO.createImageInputStream(new File(filePath));
try {
Iterator<ImageReader> readers = ImageIO.getImageReaders(input);
if (readers.hasNext()) {
ImageReader reader = readers.next();
try {
reader.setInput(input);
BufferedImage image = reader.read(0); // Read the same image as ImageIO.read
// Do stuff with image...
// When done, either (1):
String format = reader.getFormatName(); // Get the format name for use later
if (!ImageIO.write(image, format, outputFileOrStream)) {
// ...handle not written
}
// (case 1 done)
// ...or (2):
ImageWriter writer = ImageIO.getImageWriter(reader); // Get best suitable writer
try {
ImageOutputStream output = ImageIO.createImageOutputStream(outputFileOrStream);
try {
writer.setOutput(output);
writer.write(image);
}
finally {
output.close();
}
}
finally {
writer.dispose();
}
// (case 2 done)
}
finally {
reader.dispose();
}
}
}
finally {
input.close();
}
BufferedImage does not have a "format"
Once the bytes have been translated into a BufferedImage the format of the source file is completely lost, the contents represent a raw byte array of the pixel information nothing more.
Solution
You should use the Tika library to determine the format from the original byte stream before the BufferedImage is created and not rely on file extensions which can be inaccurate.
One could encapsulate the BufferedImage and related data in class instance(s) like so:
final public class TGImage
{
public String naam;
public String filename;
public String extension;
public int layerIndex;
public Double scaleX;
public Double scaleY;
public Double rotation;
public String status;
public boolean excluded;
public BufferedImage image;
public ArrayList<String> history = new ArrayList<>(5);
public TGImage()
{
naam = "noname";
filename = "";
extension ="";
image = null;
scaleX = 0.0;
scaleY = 0.0;
rotation = 0.0;
status = "OK";
excluded = false;
layerIndex = 0;
addHistory("Created");
}
final public void addHistory(String str)
{
history.add(TGUtil.getCurrentTimeStampAsString() + " " + str);
}
}
and then use it like this:
public TGImage loadImage()
{
TGImage imgdat = new TGImage();
final JFileChooser fc = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter("Image Files", "jpg", "png", "gif", "tif");
fc.setFileFilter(filter);
fc.setCurrentDirectory(new File(System.getProperty("user.home")));
int result = fc.showOpenDialog(this); // show file chooser
if (result == JFileChooser.APPROVE_OPTION)
{
File file = fc.getSelectedFile();
System.out.println("Selected file extension is " + TGUtil.getFileExtension(file));
if (TGUtil.isAnImageFile(file))
{
//System.out.println("This is an Image File.");
try
{
imgdat.image = ImageIO.read(file);
imgdat.filename = file.getName();
imgdat.extension = TGUtil.getFileExtension(file);
info("image has been loaded from file:" + imgdat.filename);
} catch (IOException ex)
{
Logger.getLogger(TGImgPanel.class.getName()).log(Level.SEVERE, null, ex);
imgdat.image = null;
info("File not loaded IOexception: img is null");
}
} else
{
imgdat = null;
info("File not loaded: The requested file is not an image File.");
}
}
return imgdat;
}
Then you have everything relevant together in TGImage instance(s).
and perhaps use it in an imagelist like so:
ArrayList<TGImage> images = new ArrayList<>(5);

Categories