| 
		
	
	
	
		
	Posts: 3 
	Threads: 1 
	Joined: Jul 2025
	
 Reputation: 
0 Gimp version: 
 Operating system(s): Windows 11
	 
	
	
		Hello, 
I don't know, whether such a feature is realizable without certain changes to the Gio, but let me just describe my intent:
 
In a plugin, I want to send an "copy" of current image to a service using urllib.request.Request. Currently, I save the png image as usual using Gimp.file_save(), reopen it to read the data as bytes and attach them to a boundarized body. Then I send this body using the content-type 'multipart/form-data; boundary=xxxx' to the web service. I get an answer, evaluate the response and add the retrieved image to a new created layer. This all is working well and stable.
 
But I just want to get rid of storing the image into a file and read it again to a byte buffer. Already tried Gio.File.new_for_uri() and point the uri to memory, but my current knowledge for this aspect of the Gio library is literally not existent     
Maybe there is a more elegant way to implement a in-memory file storage, as the export to PNG format is crucial.
 
Does someone has an approach in mind and could give me some pointers to study?
 
Thanks
	
		
	 
	
	
	
		
	Posts: 6,914 
	Threads: 296 
	Joined: Oct 2016
	
 Reputation: 
605 Gimp version: 
 Operating system(s): Linux
	 
	
	
		Probably unnecessary optimization. Your file is still cached in the RAM buffers so it won't be reread from disk. 
 Otherwise I would see if perhaps GEGL can do a PNG encoding to a ram buffer.
 
 Kudos for using urlllib. I thought us humans were better off using requests?
 
		
	 
	
	
	
		
	Posts: 3 
	Threads: 1 
	Joined: Jul 2025
	
 Reputation: 
0 Gimp version: 
 Operating system(s): Windows 11
	 
	
	
		Hi ofnuts, 
thanks for your very fast response, highly appreciated    
And thank you for the pointer, I will try to find information about this GEGL topic. I've also a maybe-working way by implementing the Gio.File interface in plain python to utilize only memory storage and offer a method to return the bytes when appending it to request. But this could be some pain and may not fully working or instable, I think. What do you think about this approach?
 
Yes, urllib instead of request is used, because of the fact, that I implemented the plugin for Gimp 2.10 as well, which seems not to ship 'requests', but urllib, and I don't want users are forced to install additional libs if it is not necessary. Finally, I come from the Java world and like the feeling of Apache Http Client, where you can control every aspect of the connection by yourself.
	
		
	 
	
	
	
		
	Posts: 6,914 
	Threads: 296 
	Joined: Oct 2016
	
 Reputation: 
605 Gimp version: 
 Operating system(s): Linux
	 
	
	
		 (07-20-2025, 06:20 AM)DunkleMaterie Wrote:  And thank you for the pointer, I will try to find information about this GEGL topic. I've also a maybe-working way by implementing the Gio.File interface in plain python to utilize only memory storage and offer a method to return the bytes when appending it to request. But this could be some pain and may not fully working or instable, I think. What do you think about this approach? 
Frankly? Waste of time. What problem are you trying to solve? How will a memory file be significantly better that a file mapped to a tmpfs (on Linux you can count on /run/user/{id} ) or even a plain filesystem given the existence of file buffers all over the place? 
Otherwise, Gio has MemoryInputStream  and MemoryOutputStream .
	 
		
	 
	
	
	
		
	Posts: 3 
	Threads: 1 
	Joined: Jul 2025
	
 Reputation: 
0 Gimp version: 
 Operating system(s): Windows 11
	 
	
	
		Yes, you are right. It would be total waste of time. I "solved" it now. "Solved" because, it is not beautiful code, but better, than storing a file on drive (Windows does not have such a feature as "tmpfs" as far as I know), which is deleted immediately after the sending, only needs to exist to retrieve the png bytes. 
The solution makes use of Gegl.Node for a preprocessing to convert the Gimp.Layer into a GdkPixbuf in order to store it as png using save_to_bufferv().
 
I want to share it anyway, maybe somebody find it useful or as inspiration:
 
Code:
 def export_layer_to_png_bytes(layer:Gimp.Layer) -> bytes:"""
 Converts a given layer into PNG bytes after applying gamma correction.
 
 Parameters:
 layer (Gimp.Layer): The input layer to be converted.
 
 Returns:
 bytes: The PNG bytes representing the converted image.
 """
 Gegl.init(None)
 
 width = layer.get_width()
 height = layer.get_height()
 source_buffer = layer.get_buffer()
 
 # Gamma correction for GdkPixbuf
 node = Gegl.Node()
 # Input node
 load = node.create_child("gegl:buffer-source")
 # Unpremultiply node
 unpremul = node.create_child("gegl:unpremultiply")
 # Gamma correction node
 gamma = node.create_child("gegl:gamma")
 # Output node
 save = node.create_child("gegl:write-buffer")
 
 # Connect the source buffer from input layer to input node
 load.set_property("buffer", source_buffer)
 
 # Connect a result buffer to output layer node
 result_buffer = Gegl.Buffer.new("RGBA u8", 0, 0, width, height)
 save.set_property("buffer", result_buffer)
 
 # Set gamma correction to non-linear sRGB for GdkPixbuf
 gamma.set_property("value", 1.0 / 2.2)
 
 # Now connect the graph nodes to each other [load] -> [unpremul] -> [gamma] -> [save]
 load.connect_to("output", unpremul, "input")
 unpremul.connect_to("output", gamma, "input")
 gamma.connect_to("output", save, "input")
 
 # Baam!
 save.process()
 
 # Help to retrieve the bytes from result buffer after gamma correction for GdkPixbuf conversion
 rect = Gegl.Rectangle.new(0, 0, width, height)
 pixel_bytes = result_buffer.get(rect, 1.0, "RGBA u8", Gegl.AbyssPolicy.CLAMP)
 
 rowstride = width * 4
 gbytes = GLib.Bytes.new(pixel_bytes)
 pixbuf = GdkPixbuf.Pixbuf.new_from_bytes(gbytes, GdkPixbuf.Colorspace.RGB, True, 8, width, height, rowstride)
 
 success, png_bytes = pixbuf.save_to_bufferv("png", [], [])
 if not success:
 Gimp.message("Pixbuf export to png bytes failed")
 png_bytes = bytes()
 
 return png_bytes
		
	 |