0

I have two independant pieces of code that I need to work together, one written by myself and one that is from another project. I essentially have one part of the project that is creating a buffered image. Here is a snippet from it:

BufferedImage screenshot = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);

In the other piece of software, it accepts an image file to then pass on as JSON/POST data for another service. Here is it accepting a file:

try(InputStream file = new FileInputStream("temp.png")) {
                sendFile(out, "file", file, "temp.png");
            }

I don't have much experience working with Images in Java, my current solution is to have the first program write the BufferedImage to a file like this:

File tempFile = new File("/", "temp.png");
ImageIO.write(screenshot, "PNG", tempFile);

Then the second piece of code is able to deal with it properly. The problem arises from it needing to delete the temp file and the issues of arising from that. Is there any way to simplify this? Thanks in advance.

Evan Edwards
  • 182
  • 11
  • So the other program requires to receive the image as a file? Or can it accept something like a ByteStream? – Docteur Oct 19 '20 at 05:49
  • Yes, a byte stream would be better. If not, you can create a temporary file and then use `deleteOnExit()` which will remove the file when the JVM terminates. https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/File.html#createTempFile(java.lang.String,java.lang.String,java.io.File) – markspace Oct 19 '20 at 05:52
  • @Docteur It requires the image as a file, it could potentially work with a ByteStream but I have not tested it yet/it would require modifications to code that is not mine. It looks like that might be the way to do it. I don't have much experience with Java I/O so I'll need to read up on the docs. – Evan Edwards Oct 19 '20 at 05:53
  • Yeah, if you *have* to pass it as an image I agree with @markspace on using something like a temp file with deleteOnExit(). Changing the other code might be non-trivial, especially if it's not meant to listen for a stream and is instead a utility ran with an input. – Docteur Oct 19 '20 at 05:55
  • 1
    It looks like the sendFile-method doesn't necessarily need a 'file' but an 'InputStream'. So you could try to create one like here: https://stackoverflow.com/a/5194876/11905620. – MaS Oct 19 '20 at 05:57
  • How big are these things? If you could keep these in memory, you could use a ByteArray and the stream classes that write to and read from such a thing. This would avoid the temp file. - oh...I see you mention something sorta like that above and wonder if it would work. Since `sendFile()` takes an InputStream, and ImageIO.write can take an OutputStream, it would definitely work. – CryptoFool Oct 19 '20 at 05:59
  • @Docteur would it be better to have my code delete it after its used, rather then wait for the JVM to terminate? It could be creating a few hundred images in an hour depending on circumstances. – Evan Edwards Oct 19 '20 at 06:00
  • @Steve about 300kb each. Anywhere from 0-100 being created every hour. They are only needed for a few seconds to send to an external service. – Evan Edwards Oct 19 '20 at 06:02
  • 1
    @EvanEdwards If you can reliably know when a file is done being used, yeah, you can just delete them yourself. If both services are running constantly, though, it's probably better to refactor to use streams. :-) – Docteur Oct 19 '20 at 06:04
  • 1
    @EvanEdwards, sounds like keeping them in an "in memory file", in other words, a ByteArray via ByteArrayInput/OutputStream might be perfect then. – CryptoFool Oct 19 '20 at 06:04
  • 1
    Sounds good, thank you all for the help. I'll read up some more and attempt to fix this tomorrow morning! – Evan Edwards Oct 19 '20 at 06:05

1 Answers1

0

Solution was found thanks to the link from @Mas and commenters.

The first set of code had a ByteArrayOutputStream added called "screenshotOutput"

ByteArrayOutputStream screenshotOutput = new ByteArrayOutputStream();
ImageIO.write(screenshot, "png", screenshotOutput);

The second set of code was modified to accept a ByteArrayInput stream.

try(InputStream file = new ByteArrayInputStream(screenshotOutput.toByteArray());) {
                sendFile(out, "file", file, "temp.png");
            }

This fixed my issue. Thank you again to the commenters from yesterday.

Evan Edwards
  • 182
  • 11