wrong background color for subsequent frame creating a GIF - python-imaging-library

I'm trying to resize a gif in a smaller version.
this is what i come up with at the moment:
from PIL import Image
def process_gif(in_path, out_path= 'out.gif', size= (32,32)):
with Image.open(in_path) as im :
images = []
durations = []
for i in range(im.n_frames - 1, -1, -1):
im.seek(i)
im.thumbnail(size, Image.Resampling.LANCZOS) # noqa
im_temp = im.copy()
images.insert(0, im_temp)
durations.append(im.info['duration'])
images[0].save(
out_path,
format='gif',
interlace=True,
save_all=True,
append_images=images[1 :],
loop=0,
duration=durations,
disposal=2,
background=(255,255,255,255),
optimize=False
)
when i try to create the gif the first frame have the correct background and the rest have isssue.
with this gif as imput in.gif
i get those frame in the images before saving: 0 1 2 3
and this is the output out.gif
spent some time figuring out where is the error with no clue, the output should have trasparent background in every frame of the GIF
P.S. i noticed imgur colored the trasparent frame, the in.gif, 0, 1, 2, 3 all have trasparent background, open with your image viewer should let you see better
After some other attemp i looked for trasparency doing print(im_temp.info) before inserting the resized image, NOTE that the cycle it's backward to solve another issue so it's last frame to first frame
{'version': b'GIF89a', 'background': 0, 'loop': 0, 'duration': 70}
{'version': b'GIF89a', 'background': 0, 'loop': 0, 'duration': 70}
{'version': b'GIF89a', 'background': 0, 'loop': 0, 'duration': 70}
{'version': b'GIF89a', 'background': 0, 'loop': 0, 'duration': 70, 'transparency': 48, 'extension': (b'NETSCAPE2.0', 219)}

from PIL import GifImagePlugin
GifImagePlugin.LOADING_STRATEGY = GifImagePlugin.LoadingStrategy.RGB_AFTER_DIFFERENT_PALETTE_ONLY
using this solved my problem

Related

thumbnail function get error after one interation

working on a program to resize a gif, after the first cycle the program crash
from PIL import Image
from icecream import ic
def process_gif(in_path, out_path= 'out.gif', size= (32,32)):
with Image.open(in_path) as im :
images = []
durations = []
for i in range(im.n_frames) :
im.seek(i)
ic(im.size)
im.load()
im.thumbnail(size, Image.Resampling.LANCZOS) # noqa
ic(im.size)
im.convert('RGBA')
im_temp = Image.new('RGBA', im.size, (0, 0, 0, 0))
im_temp.paste(im, (0, 0))
images.append(im_temp)
ic(im_temp.size)
durations.append(im.info['duration'])
images[0].save(
out_path,
interlace=True,
save_all=True,
append_images=images[1 :],
loop=0,
duration=durations,
disposal=2,
background=255,
optimize=False
)
this is the console print out, as we can see it resize the first photogram with no problem, but at the second iteration it raise an error
ic| im.size: (111, 128)
ic| im.size: (28, 32)
ic| im_temp.size: (28, 32)
ic| im.size: (111, 128)
Traceback (most recent call last):
File "C:\Users\lenovo\Desktop\get_emoji\image\process_gift_1.py", line 35, in <module>
process_gif('571097748154089472.gif')
File "C:\Users\lenovo\Desktop\get_emoji\image\process_gift_1.py", line 12, in process_gif
im.thumbnail(size, Image.Resampling.LANCZOS) # noqa
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\lenovo\AppData\Local\Programs\Python\Python311\Lib\site-packages\PIL\Image.py", line 2538, in thumbnail
im = self.resize(size, resample, box=box, reducing_gap=reducing_gap)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\lenovo\AppData\Local\Programs\Python\Python311\Lib\site-packages\PIL\Image.py", line 2093, in resize
im = im.resize(size, resample, box)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\lenovo\AppData\Local\Programs\Python\Python311\Lib\site-packages\PIL\Image.py", line 2115, in resize
return self._new(self.im.resize(size, resample, box))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: box can't exceed original image size
I have no idea on how to solve this, theoreticly it should cycle all the photogram, i know for fact that the error are caused by thumbnail because if i remove it the program can reassemble the original gif
for i in range(im.n_frames) :
im.seek(i)
im.convert('RGBA')
im_temp = Image.new('RGBA', im.size, (0, 0, 0, 0))
im_temp.paste(im, (0, 0))
im_temp.thumbnail(size, Image.Resampling.LANCZOS)
images.append(im_temp)
doing this way resolve the problem, i think im.size pick the first frame of the gif i transformed so the size didn't match the actual size of the consecutive frame, but the size of the processed frame, in fact doing
for i in range(im.n_frames - 1, 0, -1):
im.seek(i)
im.thumbnail(size, Image.Resampling.LANCZOS)
im.convert('RGBA')
im_temp = Image.new('RGBA', im.size, (0, 0, 0, 0))
im_temp.paste(im, (0, 0))
images.append(im_temp)
also works fine

Is there any replacement for "GtkRuler" in GTK3?

I want to display the horizontal and vertical ruler on the frame with gtk3.
this is my frame:
I want to display ruler on the frame like this:
BUT GtkRuler has been removed from GTK 3 for being unmaintained and too specialized!!
this is my GTK3/c cpde:
/* The horizontal ruler goes on top. As the mouse moves across the
* drawing area, a motion_notify_event is passed to the
* appropriate event handler for the ruler. */
hrule = gtk_hruler_new ();
gtk_ruler_set_metric (GTK_RULER (hrule), GTK_PIXELS);
gtk_ruler_set_range (GTK_RULER (hrule), 7, 13, 0, 20);
g_signal_connect_swapped (area, "motion_notify_event",
G_CALLBACK (EVENT_METHOD (hrule, motion_notify_event)),
hrule);
gtk_table_attach (GTK_TABLE (table), hrule, 1, 2, 0, 1,
GTK_EXPAND|GTK_SHRINK|GTK_FILL, GTK_FILL, 0, 0);
/* The vertical ruler goes on the left. As the mouse moves across
* the drawing area, a motion_notify_event is passed to the
* appropriate event handler for the ruler. */
vrule = gtk_vruler_new ();
gtk_ruler_set_metric (GTK_RULER (vrule), GTK_PIXELS);
gtk_ruler_set_range (GTK_RULER (vrule), 0, YSIZE, 10, YSIZE );
g_signal_connect_swapped (area, "motion_notify_event",
G_CALLBACK (EVENT_METHOD (vrule, motion_notify_event)),
vrule);
gtk_table_attach (GTK_TABLE (table), vrule, 0, 1, 1, 2,
GTK_FILL, GTK_EXPAND|GTK_SHRINK|GTK_FILL, 0, 0);
What ideas on how to solve this task would you suggest? Or on what resource on the internet can I find help?
If your code has a compatible license, you can simply copy the GtkRuler out of GTK 2 into your code, making any changes necessary to make it work with GTK 3.

How to draw on canvas using Cairo and GTK in Julia

I'm trying to use Julia with GTK and Cairo to draw onto a canvas. I think the following code (adapted from the example fragments on the GTK.jl page) should work, but it does not. (Other GTK widgets work, but not the canvas)
I would appreciate if someone can suggest what is wrong with this code, or give a pointer to a complete example.
using Gtk.ShortNames
using Cairo
function drawfn(w)
ctx = Gtk.getgc(w)
Cairo.set_coords(ctx, 0, 0, 800, 600, 0, 800, 0, 600)
h = Gtk.height(w)
w = Gtk.width(w)
Gtk.rectangle(ctx, 0, 0, w/2, h/2)
Gtk.set_source_rgb(ctx, 0, 0, 1)
Gtk.fill(ctx)
end
function main()
win = Gtk.#Window("stuff", 800,600)
c = Gtk.#Canvas()
Gtk.push!(win,c)
Gtk.draw(drawfn, c)
Gtk.showall(win)
end
main()
I think this was a bug in version 0.8.1 of Gtk.jl. I posted an issue to github after which vtjnash fixed it immediately and tagged version 0.8.2.

polyhedron in openSCAD yields "No top level geometry to render"

I do not get why this polyhedron gives me a "no top level geometry to render" error. All triangles are correctly oriented, "thrown-together"-view shows only yellow outside faces. This is my code:
top_width=39;
bottom_width=51;
col_offset=6;
length=160;
height=40;
rows=10;
cols=40;
top_row_width=top_width/rows;
bottom_row_width=bottom_width/rows;
col_length=length/cols;
walls=0.4;
box();
module box(){
polyhedron(
points=[
[ // point 0
0,
0,
height
],[ // point 1
length,
0,
height
],[ // point
length,
top_width,
height
],[ // point 3
0,
top_width,
height
],[ // point 4
0,
0+col_offset,
0
],[ // point 5
length,
0+col_offset,
0
],[ // point 6
length,
bottom_width+col_offset,
0
],[ // 7
0,
bottom_width+col_offset,
0
]
],
triangles=[
[3,1,0],
[3,2,1],
[4,5,6],
[4,6,7],
[7,2,3],
[6,2,7],
[4,3,0],
[4,7,3],
[1,2,5],
[1,2,5],
[2,6,5],
[0,1,5],
[0,5,4]
]
);
}
Any hint is very appreciated, thanks in advance!
Well I'm baffled too. Latest version of OpenSCAD supports faces in place of triangles:
faces = [
[0,3,2,1],
[0,1,5,4],
[1,2,6,5],
[2,3,7,6],
[0,4,7,3],
[4,5,6,7] ]
and that renders OK.
You might try asking on the OpenSCAD forum http://forum.openscad.org/ which is more active than here.

Formatting data for CoreImage CIColorCube

I'm trying to apply arbitrary 3D Luts to images on iOS, but I'm stuck.
I can't for the life of me figure out how to correctly format the cube data for CIColorCube.
I've done what I can based on the brief screen grabs I've taken from the WWDC videos, but what I really need is some sort of working template to go from.
Are there any docs with an example of a hard coded cube rather than the procedural ICC generated ones shown in the ImageApp sample code?
Right now my cube data looks like what you see below (with the middle chopped out for brevity).
Its throwing the error:
"Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<CIColorCube 0xb46a850> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key inputCubedata.'"
Any help would be much appreciated, I'm tearing my hear out over this one. I can't find any sold examples of what CIColorCube is expecting (As in a working example, not just a explanation).
uint8_t color_cube_data[4096*4] = {
0, 0, 0, 1,
17, 0, 0, 1,
33, 0, 0, 1,
51, 0, 0, 1,
68, 0, 0, 1,
84, 0, 0, 1,
102, 0, 0, 1,
119, 0, 0, 1,
-----etc etc etc
153, 255, 255, 1,
170, 255, 255, 1,
186, 255, 255, 1,
204, 255, 255, 1,
221, 255, 255, 1,
237, 255, 255, 1,
255, 255, 255, 1
};
I can't help with all your problems without more info, but I think your current error may be cause by this. Make sure the line of code setting your cube data reads like this...
[_colorCube setValue:color_cube_data forKey:#"inputCubeData"];
not this...
[_colorCube setValue:color_cube_data forKey:#"inputCubedata"];
3D LUT has to be wrapped into NSData before passed as an argument to the CIFilter. Cube values are in range [0.0 : 1.0]
NSData * cube_data = [NSData dataWithBytes:color_cube_data length:4096*sizeof(float)*4];
[filter setValue:input_image forKey:#"inputImage"];
[filter setValue:cube_data forKey:#"inputCubeData"];
[filter setValue:[NSNumber numberWithFloat:16] forKey:#"inputCubeDimension"];
Value for inputCubeDimension is strictly power of two.