B4J Question image.writetostream using disk - how to avoid it ?

Magma

Expert
Licensed User
Longtime User
Hi there...

well i am using this fabulous snippet [B4X][XUI] Image to JPEG byte array with resize/quality options but... i ve met something that don't want to have, the image.writetostream is using hdd/ssd when want to compress quality of jpeg... is it possible to avoid... ?

If you have a timer and some/many XUIImageToJPEGByteArray ..and go a "walk" at appdata\local\temp you will see a lot of imageioxxxxxxxxxxxxxxxxxxxxxxxx.tmp files creating/deleting for doing the job... this reading/writting to disk creates a delay to that i want to do...

B4X:
    Dim out As OutputStream
    out.InitializeToBytesArray(0)
    image.WriteToStream(out, quality,  "JPEG")  'That seems creating .tmp file to do the job....
    out.Close

is it possible using something different to do my job faster / on the fly... ?

ps: i am sure... that ImageWriter/imageio do the same in java...
 
Last edited:

Magma

Expert
Licensed User
Longtime User
Upvote 0

Magma

Expert
Licensed User
Longtime User
See if this post can solve what you wanted (especially post#13):
[B4X] Reduce an image file to a specific size - for example, <500KB to upload to the Forum

I don't understand why image.WriteToStream() generates *.tmp, should not.
Thanks for answer... but yes it is creating... actually the XUIImageToJPEGByteArray is a class by OliverA .. but writetostream creates tmp files... if go at appdata/local/temp.. you ll see.. the time of running... when end.. delete them... automatically

May be is memory management of java..
 
Upvote 0

kimstudio

Active Member
Licensed User
Longtime User
Yes I realized that you may already use in memory processing... the problem is just the *.tmp using hdd/sdd.
I think it is a severe problem and will impact performance to some extent. I will try it on my PC also.
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
Yes I realized that you may already use in memory processing... the problem is just the *.tmp using hdd/sdd.
I think it is a severe problem and will impact performance to some extent. I will try it on my PC also.
I will wait your news.. May be need to add a loop to see the effect..

But the real problem will be with what will exchange that.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
but writetostream creates tmp files.
It's actually Java's ImageWriter class's write method that creates the temp files, even when working with a memory byte array as the destination.

Source:

Note:
The article also mentions lingering temp files. According to @Magma, the files are removed, but does this happen immediately or only after the program terminates? If it is after the program terminates, then the B4XBitmap class may need to implement the dispose method of the ImageWriter class. B4XBitmap currently does not, see https://github.com/AnywhereSoftware...software/b4a/objects/B4XViewWrapper.java#L818
 
Upvote 0

kimstudio

Active Member
Licensed User
Longtime User
You are right. It generates *.tmp files with size of 0 Bytes and automatically deleted all of them after I close the MainForm.

屏幕截图 2022-10-26 210638.png


As Erel said if it is Java SDK thing and no impact then I guess it is hard to do anything about it except to find another in memory jpeg compression code module.
 
Upvote 0

kimstudio

Active Member
Licensed User
Longtime User
but does this happen immediately or only after the program terminates?

My observation for an app to create 10 writes is: after 10 tmp files generated, after several seconds, 7 of them are deleted, then after I close the app, all left ones are deleted.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
My observation for an app to create 10 writes is: after 10 tmp files generated, after several seconds, 7 of them are deleted, then after I close the app, all left ones are deleted.
That should indicate that, as is, the garbage collector is kicking in the removal of the temp files. So the question is, should B4XBitmap continue to rely on the garbage collector or should it implement the dispose method in order to remove the temp files?
 
Upvote 0

Magma

Expert
Licensed User
Longtime User
You are right. It generates *.tmp files with size of 0 Bytes and automatically deleted all of them after I close the MainForm.

View attachment 135288

As Erel said if it is Java SDK thing and no impact then I guess it is hard to do anything about it except to find another in memory jpeg compression code module.
I think the 0 size... is because the files not closing... if you check live the size of disk changing ... is always the size of jpeg file..

The files deleted after imageio.writetostream execution

I am not so familiar with Java.. must find.. a memory jpeg or other picture format compression code module.
 
Last edited:
Upvote 0

Magma

Expert
Licensed User
Longtime User
Sorry coming again to the same... but may be this help others... too.. searching the web found the following:

ps:eek:fcourse jDeli is very expensive !!!!

But searching little found that also opencv has options to encode bufferedimage to the memory... I think @JordiCP .. already know if it is better... but for sure as i am reading it (has a difficulty, mat, etc)...

And something else that found was that... but i didn't checked...

B4X:
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public byte[] toByteArray(BufferedImage image) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();          
    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(baos);
    encoder.encode(image);          
    return baos.toByteArray();
}

...read about com.sun.image.codec ... that will depreceated... but i am not sure... also i am not sure if it is ok to use them at b4j and create commercial software (if needed)

other solution will Apache Commons Imaging... but no java example for them too..

so we have:
jDeli... very expensive
Sun image codecs ... i didn;t try... not sure if working and if will work tomorrow... also.. what about their license
opencv
JAI ... Java Advance Imaging has imageio... and many talking that is better ? but why?
Apache Commons..

too many options but... which is faster and free :cool:
need little more searching.. my eyes are "playing"... need a sleep

ps: also found that gif encoding will be much better for my scope... as the bytes using is 1/4 --> no need million of colors
 
Upvote 0

kimstudio

Active Member
Licensed User
Longtime User
need little more searching..
Like OpenCV, there are many other pure imageio libs in C/C++ can be used, for example this one:
https://github.com/AbePralle/ImageIO has a much simpler interface and I think it can be easy to make an interface for java and B4J to call dll on Windows.

ps: also found that gif encoding will be much better for my scope... as the bytes using is 1/4 --> no need million of colors
Are you sure as gif only supports 256 colors and it is a lossless format which means its compression only works better for less detailed images.
 
Upvote 0

OliverA

Expert
Licensed User
Longtime User
I've created an OpenCV version of the XUIImageToJPEGByteArray snippet. It seems about a tad over 2x faster than the XUI... version and a little under 2x faster than the original inline ImageToJPEGByteArray snippet (testing 1000 iterations over each version). The OpenCV is based on the original inline version, replacing the section that creates the byte array with OpenCV methods instead of using ImageWriter. I don't know if this new version uses any temp files (yeah, I'm lazy), nor do I know what the memory impact of the new version is compared to the previous two. Also, keep in mind, you'll add about 45+MB of libraries (one .jar and one .dll) for OpenCV (using version 4.60). I'll post it as a snippet and link it here once done.
 
Upvote 0
Top