Image.loadFromFile() does not close the file
KnorrFG opened this issue · 6 comments
Reading an image with the method mentioned above will leave the file open, which makes it impossible to delete or overwrite it on Windows.
I have this issue too, are there any workarounds?
NiGui does not open the file itself, it calls GdipCreateBitmapFromFile
to load the file. Apparently Windows does not close the file. I found this: https://stackoverflow.com/questions/4978419/c-gdi-loading-an-image-from-a-file-then-deleting-the-file-before-unloading
I researched it a bit more yesterday too.
It might be what you found, but since there is no option to close the file handle in the gdiplus flat api , it might be something to do with lazy compression instead.
However, the problem might also be with the flat api itself:
from here
Seems like changing GdipCreateBitmapFromFile to GdipCreateBitmapFromStream might fix this problem tho.
apparently GdipDisposeImage() should also work for bitmaps, however even if i use that i still get the problem
here is an example of what im trying to do:
import nigui
app.init()
var window = newWindow("minimal")
window.width = 300.scaleToDpi
window.height = 300.scaleToDpi
var openImageButton = newButton("open")
var controlsContainer = newLayoutContainer(Layout_Vertical)
window.add controlsContainer
controlsContainer.add openImageButton
openImageButton.onClick = proc(event: ClickEvent) =
var image = newImage()
image.loadFromFile("minimal.png")
var imageWindow = newWindow("Preview")
imageWindow.width = image.width
imageWindow.height = image.height
var control1 = newControl()
control1.widthMode = WidthMode_Fill
control1.heightMode = HeightMode_Fill
imageWindow.add control1
control1.onDraw = proc(event: DrawEvent) =
let canvas = event.control.canvas
canvas.drawImage(image, 0, 0, image.width, image.height)
imageWindow.show()
var saveImageButton = newButton("save")
controlsContainer.add saveImageButton
saveImageButton.onClick = proc(event: ClickEvent) =
var image = newImage()
image.loadFromFile("minimal2.png")
image.saveToPngFile("minimal.png")
window.show()
app.run()
the open button opens minimal.png in a new window as preview
the copy button overrides minimal.png
after i close the preview window, copy cant access minimal.png
I tried adding:
# platform_impl.nim line 392
proc pGdipDisposeImage(bitmap: var pointer) =
let status = GdipDisposeImage(bitmap)
if status != 0:
pCheckGdiplusStatus(status, "Failed to dispose of Image")
# platform_impl.nim line 842
method dispose(image: Image) =
let canvas = cast[CanvasImpl](image.canvas)
pGdipDisposeImage(canvas.fBitmap)
# nigui.nim line 653
method dispose*(image: Image) {.base.}
# minimal.nim
imageWindow.onDispose = proc(event: WindowDisposeEvent) =
image.dispose()
which seems like it should work, but it doesn't.
The image gets disposed but the file still is not closed.