tclgd(n)

πŸ“¦ version 1.3.1, in alpine 3.24

🌸 NAME 🌸

tclgd β€” a modern, nearly feature-complete interface to gd-2 graphics drawing routines πŸ’…

✨ SYNOPSIS ✨

package require tclgd

GD create objName width height
GD create_truecolor objName width height
GD create_from_jpeg objName channel
GD create_from_jpeg_data objName data
GD create_from_png objName channel
GD create_from_png_data objName data
GD create_from_gif objName channel
GD create_from_gif_data objName data
GD create_from_gd objName channel
GD create_from_gd_data objName data
GD create_from_gd2 objName channel
GD create_from_gd2_data objName data
GD create_from_gd2_part objName channel x y width height
GD create_from_gd2_part_data objName data x y width height
GD create_from_wbmp objName channel
GD create_from_wbmp_data objName data
GD create_from_xbm objName fileHandle
GD create_from_xpm objName fileHandle

objName pixel x y ?color?
objName pixelrgb x y ?color?
objName line x1 y1 x2 y2 color
objName polygon ?filled|open? pointList color
objName rectangle x1 y1 x2 y2 color
objName filled_rectangle x1 y1 x2 y2 color
objName arc cx cy width height startDegrees endDegrees color
objName filled_arc cx cy width height startDegrees endDegrees color
?arc? ?chord? ?pie? ?nofill? ?edged?
objName filled_ellipse cx cy width height color
objName fill_to_border x y borderColor color
objName fill x y color
objName text color font pointSize angle x y text
objName text_bounds color font pointSize angle x y text
objName allocate_color r g b ?alpha?
objName closest_color r g b ?alpha?
objName closest_color_hwb r g b
objName exact_color r g b ?alpha?
objName resolve_color r g b ?alpha?
objName total_colors
objName deallocate_color color
objName true_color r g b ?alpha?
objName interlace ?boolean?
objName transparent ?color?
objName set_anti_aliased color
objName set_anti_aliased_dont_blend color
objName set_brush brushImageCommand
objName set_tile tileImageCommand
objName set_style colorList
objName set_thickness thickness
objName alpha_blending blending
objName save_alpha boolean
objName get_alpha colorIndex
objName clip ?x1 y1 x2 y2?
objName bounds_safe x y
objName green_component color
objName red_component color
objName blue_component color
objName rgb_components color
objName width
objName height
objName copy srcImageCommand destX destY srcX srcY width height
objName copy_resized srcImageCommand destX destY srcX srcY destWidth
destHeight srcWidth srcHeight
objName copy_resampled srcImageCommand destX destY srcX srcY destWidth
destHeight srcWidth srcHeight
objName copy_rotated srcImageCommand destX destY srcX srcY destWidth
destHeight srcWidth srcHeight angle
objName copy_merge srcImageCommand destX destY srcX srcY width height
percent
objName copy_merge_grey srcImageCommand destX destY srcX srcY width
height percent
objName copy_palette srcImageCommand
objName sharpen percent
objName compare otherImageCommand
objName compare_ratio otherImageCommand
objName square_to_circle name radius
objName rewrite_color oldColor newColor
objName write_jpeg channel quality
objName jpeg_data quality
objName write_gif channel
objName gif_data
objName gif_anim_begin channel global_color_map loops
objName gif_anim_add channel local_color_map left_offset top_offset
delay disposal ?previous_image?
objName gif_anim_end channel
objName write_png channel compressionLevel
objName png_data compressionLevel
objName write_wbmp channel fgcolor
objName wbmp_data fgcolor
objName write_gd fileHandle
objName gd_data
objName write_gd2 channel chunkSize format
objName gd2_data chunkSize format

πŸ¦‹ DESCRIPTION πŸ¦‹

Okay so tclgd is literally the moment Tcl programs get to read, manipulate, and generate graphic images in a whole bunch of popular formats. Bestie, it ate. πŸ’–

The GD command spins up a brand-new Tcl command for you β€” either it preps it with an empty graphic (that's the create and create_truecolor situations), or it fills it up by reading file data from a Tcl channel, from in-memory data, or from a Tcl file handle. That last one is only for the couple of cases where a channel interface just can't be provided because the underlying gd library routines say no. 🫢

IMPORTANT: the channel you're reading should be configured for binary translation, like this πŸ‘‡ set fp [open parrots.png] fconfigure $fp -translation binary -encoding binary GD create_from_png parrots $fp

And ngl, if you keep getting corrupt image errors on images you're pretty sure are fine β€” like, you can load them into Photoshop and everything β€” you probably are not setting translation to binary. That's the vibe check failing, not the picture. 😭

For the formats where channels are supported (which is the majority, slay), literally any type of channel can be used β€” files, sockets, and if you're so equipped, alternate channel interfaces such as reading the data directly out of zip files. ✨

Once an image has been created or loaded, you manipulate it through the named object. Or, if the object name is #auto, a unique command name gets returned and you should grab it into a variable and then execute it using a reference to that variable β€” same manner as Incr Tcl, iykyk. πŸŽ€

GD create img 100 100
img pixel 5 5

🌈 DRAWING FUNCTIONS 🌈

Here's the whole girliepop toolbox, one by one πŸ‘‘

  • objName pixel x y β€” returns the color index of the pixel located at coordinates x and y. And objName pixel x y color sets that pixel location to the specified color index. Iconic little getter/setter combo. πŸ’…
  • objName pixelrgb x y β€” returns a list containing the red, green and blue values of the pixel located at coordinates x and y. Meanwhile objName pixelrgb x y color sets that pixel location to the specified color index. But fr fr, for setting, use pixel instead β€” because how or whether pixelrgb will set colors is likely to change. πŸ‘€
  • objName line x1 y1 x2 y2 color β€” draws a line from the coordinates x1, y1 to x2, y2 using color color. And if thickness is set to 1 and antialiasing is enabled, the line will be drawn antialiased. Gorgeous. πŸ¦‹
  • objName polygon ?filled|open? pointList color β€” draws a polygon of color color using points from the point list pointList, which must contain an even number of xy pairs. Even number, bestie, don't fight it. ✨
  • objName rectangle x1 y1 x2 y2 color β€” draws a rectangle of the given color from the corner at x1, y2 to the corner at x2, y2.
  • objName filled_rectangle x1 y1 x2 y2 color β€” same as rectangle except the rectangle is filled. Simple as that. πŸ’–
  • objName arc cx cy width height startDegrees endDegrees color β€” draws an arc centered on cx, cy, of the specified width and height, starting and ending at the specified degrees, and using the specified color.
  • objName filled_arc cx cy width height startDegrees endDegrees color ?arc? ?chord? ?pie? ?nofill? ?edged? β€” draws an arc centered on cx, cy, of the specified width and height, starting and ending at the specified degrees, and using the specified color. Additional options can be specified and are logically or'ed together: chord, pie, nofill and/or edged. Mix and match, main character energy. πŸ”₯
  • objName filled_ellipse cx cy width height color β€” draws a filled ellipse centered at cx, cy, of the given width, height and color.
  • objName fill_to_border x y borderColor color β€” fills to the border matching the specified borderColor, starting at x, y, using the specified color.
  • objName fill x y color β€” does a flood fill starting at x, y using the specified color.
  • objName text color font pointSize angle x y text β€” renders text using the specified font and point size, at the specified angle, starting at x, y. The font is the full or relative pathname to a TrueType font file (a .ttf or .ttc file). And heads up: Tclgd does not support GD's optionally built-in, non-antialiased, non-TrueType fonts. Not the vibe, we don't do those. πŸ™ˆ
  • objName text_bounds color font pointSize angle x y text β€” determines the bounds of text given the specified font and point size, at the specified angle, starting at x, y. The bounds come back as an 8-element list giving the x and y coordinates of the four corners of a box the text will be within. Sneak peek before you commit, we love to see it. πŸŽ€
  • objName allocate_color r g b ?alpha? β€” allocates a color given the specified red, green and blue values, and optional alpha value, and returns the color index. For truecolor images it returns a value that can be used to draw the specified color β€” but it's not really an index per se. Like, it's giving index energy, but it's not one. πŸ’…
  • objName closest_color r g b ?alpha? β€” returns the closest color index that can be found among the currently allocated colors.
  • objName closest_color_hwb r g b β€” returns the closest color based on hue, whiteness and blackness, and it's superior to closest_color. Upgrade your life. πŸ‘‘
  • objName exact_color r g b ?alpha? β€” searches the colors which have been defined thus far in the specified image and returns the index of the first color with RGB values which exactly match those of the request.
If no allocated color matches the request precisely, -1 is returned. πŸ’€
  • objName resolve_color r g b ?alpha? β€” searches the colors which have been defined thus far in the specified image object and returns the index of the first color with RGB values which exactly match those of the request. If no allocated color matches the request precisely, it tries to allocate the exact color. And if there is no space left in the color table, then it returns the index of the closest color. She's resourceful. 🧚

If applied to a truecolor image, this method always succeeds in returning the requested color. If the alpha argument is specified, then the index of the first color with matching RGBA values is returned, etc, as above. ✨

  • objName total_colors β€” returns the number of colors currently allocated in a palette image.
  • objName deallocate_color color β€” marks the specified color as being available for reuse. Recycling era. ♻️
  • objName true_color r g b ?alpha? β€” returns an RGB or RGBA color value for use when drawing on a truecolor image. If alpha is specified then alpha channel transparency is used. 🫢

Red, green and blue are all in the range between 0, off, and 255, maximum. Alpha ranges between 0, opaque, and 127 (fully transparent).

  • objName interlace ?boolean? β€” if set to 1, t, etc, causes the image to be saved interlaced if the output format supports it. If 0, f, etc, causes the image to be saved noninterlaced. And if boolean isn't specified, it returns the current interlace setting for the image. πŸ¦‹
  • objName transparent ?color? β€” says what color index will be generated as transparent when the image is saved, assuming the outputted image format supports it. If color is not specified, the current color is returned. -1 means transparency is disabled, and setting transparency to -1 disables it as well.
  • objName set_anti_aliased color β€” is used to specify the foreground color to be used when drawing antialiased lines. Smooth edges, we stay obsessed. ✨

Antialiased lines can be drawn on both truecolor and palette-based images, so no gatekeeping there ✨. But β€” and this is the fine print, bestie β€” if you try to draw antialiased lines on highly complex palette-based backgrounds, the results might not be satisfactory, because the palette just doesn't have enough colors to work with 😭. Antialiased line-drawing on simple backgrounds should work well with palette-based images though 🫢. Otherwise, please use a truecolor image instead. Periodt.

  • objName set_anti_aliased_dont_blend color β€” okay so normally, when you're drawing lines with the special antialiased color, blending colors with the background to reduce jagged edges is exactly the behavior you want πŸ’…. But sometimes? You want the line NOT to blend with one particular color when that color shows up in the background. This method is how you flag that special color, so your foreground can stand out more clearly against it πŸ”₯.
  • objName set_brush brushImageCommand β€” sets the brush for brushed drawing to be the image contained in the specified image command 🎨.
  • objName set_tile tileImageCommand β€” sets the tile for tiled drawing to be the image contained in the specified image command 🧩.
  • objName set_style colorList β€” sets the image style for styled lines to a list of colors 🌈. Each color in the list is either a color value or the word transparent, which means "leave the existing color unchanged for that particular pixel" β€” that's how you get dashed lines and such, when the color argument to the line drawing function is specified as styled πŸ‘‘

Styles and brushes can be combined to draw the brush image at intervals instead of a continuous stroke, iykyk πŸ’«. When you're making a style list to use with a brush, list elements of 0 mean pixels where the brush should not be drawn, and elements of 1 mean pixels where the brush should be drawn.

To draw a styled, brushed line, use the special color styled_brushed for the color argument to the draw method πŸ–ŒοΈ.

  • objName set_thickness thickness β€” sets the thickness of lines drawn by the line and polygon drawing functions πŸ“.
  • objName alpha_blending blending β€” so GD has two different modes for drawing on truecolor images, and this is the whole vibe check πŸ¦‹. In blending mode β€” which is on by default β€” the alpha channel component of the color you hand to each drawing function is used to determine how much of the underlying color should be allowed to shine through ✨. In this mode gd automatically blends the existing color at that point with the drawing color, storing the result in the image. In this mode, the resulting pixel is opaque (alpha channel value of zero).

In non-blending mode, the drawing color is copied literally with its alpha channel information, replacing the destination pixel with the color and alpha channel value πŸ’€. In this mode the alpha value stored in the image is whatever alpha value the pixel was drawn with β€” hence the resulting pixel in the resulting image will range from opaque to translucent depending on the alpha channel value.

Blending mode is only available with truecolor images, and PNG is currently the only file format supported by gd which can include alpha channel information πŸŽ€.

  • objName save_alpha boolean β€” by default gd does not attempt to save full alpha channel information (as opposed to single-color transparency) when saving PNG images 🌸. (PNG is currently the only gd-supported file format that can include alpha channel information.) This saves space in the output file, and honestly? respect.

If you want to create an image with a full alpha (transparency) channel, invoke the save_alpha method with an argument of 1 and also invoke the alpha_blending method with an argument of 0 to turn off alpha blending within the library β€” that way the alpha channel information gets stored in the image, rather than having gd composite the image immediately when the drawing functions are invoked πŸ’œ.

  • objName get_alpha color β€” returns the alpha component of the specified color index, where 0 is completely opaque (no blending with the background) through 127 being completely transparent (the background shines through 100%) πŸ’§.
  • objName clip ?x1 y1 x2 y2? β€” with no arguments, returns the boundaries of the current clipping rectangle πŸ“. With arguments, it sets a clipping rectangle. Once set, all future drawing operations will remain within the specified clipping area, until a new clipping rectangle is set. No escapees πŸ”’.
  • objName bounds_safe x y β€” returns true (1) if the specified point is within the current clipping rectangle, and false (0) if not βœ….
  • objName green_component color β€” returns the green component of the specific color index πŸ’š.
  • objName red_component color β€” returns the red component of the specified color index ❀️.
  • objName blue_component color β€” returns the blue component of the specified color index πŸ’™.
  • objName rgb_components color β€” returns the red, green and blue components of the color as a list 🌈.
  • objName width β€” returns the width of the image, while objName height returns the height πŸ“. Yes, they're a matching set, we love a duo 🫢.
  • objName compare otherImageCommand β€” given two images (the named object and another image command), returns a list of ways in which the two images are different πŸ‘€. The members of the list will include zero or more of the following elements:
    • image β€” if present, indicates that the images will appear differently when displayed.
    • num_colors β€” if present, indicates that the number of colors in the palettes differ.
    • colors β€” indicates that the colors differ between the two images.
    • height β€” if present, indicates that the height of the images differ.
    • width β€” if present, indicates that the width of the images differs.
    • transparent β€” if present, indicates that the transparent color differs.
    • background β€” indicates that the background color differs.
    • interlace β€” if present, indicates that one image is interlaced while the other is not.
    • truecolor β€” if present, indicates that one image is a truecolor while the other is indexed and has a palette.

If the list returned is empty, the images should be identical πŸŽ‰. If image is not present, the images will appear identically if displayed, regardless of other characteristics differing. According to the libgd documentation, any difference in the transparent color is assumed to make images display differently, even if the transparent color is not used πŸ€·β€β™€οΈ.

  • objName compare_ratio otherImageCommand β€” given two images of identical dimensions, returns the ratio of pixels that are identical between the two images, between 0.0 and 1.0 πŸ“Š.
  • objName copy srcImageCommand destX destY srcX srcY width height β€” copy a rectangular portion of one image to another image πŸ“‹. If you want to stretch or shrink the image in the process, use copy_resized or copy_resampled instead, bestie.
  • objName copy_resized srcImageCommand destX destY srcX srcY destWidth destHeight srcWidth srcHeight β€” used to copy a rectangular portion of one image to another image πŸ–ΌοΈ. The X and Y dimensions of the source and destination regions can vary, resulting in stretching or shrinking of the region as appropriate. It's giving glow-up or shrink-ray, your call πŸ’«.
  • objName copy_resampled srcImageCommand destX destY srcX srcY destWidth destHeight srcWidth srcHeight β€” this command provides "smooth" copying from a large image to a smaller one, using a weighted average of the pixels of the source area rather than selecting one representative pixel 🌸. Immaculate downscaling behavior, no cap.
  • objName copy_rotated srcImageCommand destX destY srcX srcY destWidth destHeight srcWidth srcHeight angle β€” the rotate-y one, with the extra angle argument at the end πŸ”„.
  • objName copy_merge srcImageCommand destX destY srcX srcY width height percent β€” merge two images by the specified percentage 🫱. If the percentage is 100 then it will function the same as the copy method.
  • objName copy_merge_grey srcImageCommand destX destY srcX srcY width height percent β€” the greyscale-flavored merge, same argument lineup 🩢.
  • objName copy_palette srcImageCommand β€” copies a palette from one image to another, attempting to match the colors in the target image to the colors in the source palette 🎨.
  • objName sharpen percent β€” sharpen the specified image ✨. The argument is the sharpening percentage and can be greater than 100. Silently does nothing to non-truecolor images. Silently does nothing for 0 percent. Transparency and alpha channel are not altered β€” very polite of it, honestly πŸ™ˆ.
  • objName square_to_circle name radius β€” creates a new image of the width and height radius * 2, in which the X axis of the original has been remapped to rho, the distance from the center 🌐. This is known as a polar coordinate transform, iykyk. The source image must be square.
  • objName rewrite_color oldColor newColor β€” converts all pixels with a color of oldColor to a color of newColor and returns a count of the number of pixels changed πŸ”. A full glow-up for your pixels.

πŸ–ΌοΈ IMAGE OUTPUT ROUTINES πŸ–ΌοΈ

  • objName write_jpeg channel quality β€” writes the image in JPEG format, with the specified quality level, to the specified Tcl channel πŸ“Ό, while objName jpeg_data quality will return it as binary data. Quality can range from 0 to 100, where higher numbers give higher quality 🌟.
  • objName write_gif channel β€” writes the image to the specified channel in GIF format 🎞️, while objName gif_data returns it as binary data.
  • objName write_png channel compressionLevel β€” write the image to the specified channel, with the compression level of -1 for the default set when zlib was built, 0 to indicate no compression, 1 to compress as quickly as possible, all the way to 9 to select the best possible compression πŸ—œοΈ. Likewise objName png_data compressionLevel returns the image as binary data, with the specified compression.
  • objName write_wbmp channel fgcolor β€” write the image to the specified channel in Windows bitmap format, selecting only pixels matching the specified foreground color πŸͺŸ, and objName wbmp_data fgcolor returns the image in wbmp format as binary data.
  • objName write_gd fileHandle β€” writes the image out in the high-performance but non-portable gd format ⚑, while objName gd_data returns the image as binary data.
Non-portable, bestie. It says it right there. Don't say I didn't warn you πŸ’€.
  • objName write_gd2 channel chunkSize format β€” the gd2 writer, with chunkSize and format arguments πŸ“¦.
  • objName gd2_data chunkSize format β€” writes the image out in the high-performance but non-portable gd2 format, with chunkSize determining the size of each chunk, and format being either compressed or raw πŸ”₯.

🎞️ ANIMATED GIFS 🎞️

Okay bestie, this is the fun part β€” making your GIF move. πŸ’ƒ

  • objName gif_anim_begin channel global_color_map loops β€” kicks off an animated GIF. You tell it the file channel to write to, a 1 if the global color map is gonna be used, and how many times the animation should play. And if loops is zero? The animation repeats indefinitely β€” infinite slay, no cap. β™ΎοΈβœ¨
  • objName gif_anim_add channel local_color_map left_offset top_offset delay disposal ?previous_image? β€” drops a GIF image into the animated GIF you're building. Set local_color_map to 1 to give this image its own local palette in the animation; otherwise the global palette gets used.
⚠️ Real talk: if you go with local palettes, you must make sure they match the global palette. Use the copy_palette method to copy palettes between images, iykyk. 🎨
  • left_offset and top_offset let you place the frame at an offset inside the parent frame β€” where (0, 0) parks it right in the corner. πŸ“
  • delay is the delay between the previous frame and this one, measured in hundredths of a second. ⏱️
  • disposal is one of these four vibes:
    • 0 β€” unknown
    • 1 β€” none
    • 2 β€” restore background
    • 3 β€” restore previous

Unknown is not recommended β€” don't do it, bestie. πŸ™ˆ Restore background restores the first allocated color of the global palette. Restore previous restores the appearance of the affected area from before the frame was rendered. And heads up: only none is a sensible choice for the first frame. πŸ₯‡

  • Now, if previous_image gets passed in, the built-in GIF optimizer is automatically engaged and whatever disposal method you specified is just ignored. πŸ’€ The optimizer compares the images and only writes the changed pixels to the new frame of the animation. To get good optimization, it's usually best to use a single global color map. And to let gif_anim_add compress unchanged pixels by using a transparent color, the image has to actually include a transparent color. See the gd documentation for the details. πŸ”
  • objName gif_anim_end channel β€” honestly? Self-explanatory. That's it, that's the method, we're done here. πŸ‘‘πŸŽ€

And that's the whole page, bestie β€” go make something iconic. πŸŒˆπŸ’–

This little masterpiece comes from the Tcl-Extensions manual, version 1.1, and the page itself is tclgd(n). Mwah, take care, and remember: read your docs, hydrate, and never guess at your disposal methods. πŸ«ΆπŸ¦‹πŸŒΈ

πŸ“¦ where this page comes from