Last active
August 24, 2025 16:25
-
-
Save attic-stuff/d6d3f27a1a9a8d46f3dd79181d9e95c7 to your computer and use it in GitHub Desktop.
creates a data uri from a sprite, assuming four channels of eight bit color
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * creates a data uri out of a sprite | |
| * assumes rgba, 8bit | |
| * @param {Asset.GMSprite} sprite_asset which sprite to convert to url | |
| * @param {Real} [frame_number] which frame is being converted | |
| * @return {String} | |
| */ | |
| function sprite_create_data_url(sprite_asset, frame_number = 0) { | |
| static buffer_write_u32_backwards = function(buffer, value) { | |
| buffer_write(buffer, buffer_u8, (value >> 24) & 255); | |
| buffer_write(buffer, buffer_u8, (value >> 16) & 255); | |
| buffer_write(buffer, buffer_u8, (value >> 8) & 255); | |
| buffer_write(buffer, buffer_u8, value & 255); | |
| } | |
| var png_width = sprite_get_width(sprite_asset); | |
| var png_height = sprite_get_height(sprite_asset); | |
| var crc_begin = 0; | |
| var crc_length = 0; | |
| var crc_hash = 0; | |
| var png_buffer = buffer_create(1, buffer_grow, 1); | |
| //write header | |
| buffer_write(png_buffer, buffer_u64, | |
| 137 | (80 << 8) | (78 << 16) | (71 << 24) | (13 << 32) | (10 << 40) | (26 << 48) | (10 << 56)); | |
| //write ihdr | |
| buffer_write_u32_backwards(png_buffer, 13); | |
| crc_begin = buffer_tell(png_buffer); | |
| buffer_write(png_buffer, buffer_text, "IHDR"); | |
| buffer_write_u32_backwards(png_buffer, png_width); | |
| buffer_write_u32_backwards(png_buffer, png_height); | |
| buffer_write(png_buffer, buffer_u8, 8); | |
| buffer_write(png_buffer, buffer_u32, 6); | |
| crc_length = buffer_tell(png_buffer) - crc_begin; | |
| crc_hash = buffer_crc32(png_buffer, crc_begin, crc_length) ^ 0xffffffff; | |
| buffer_write_u32_backwards(png_buffer, crc_hash); | |
| //filter sprite | |
| var png_surface = surface_create(png_width, png_height); | |
| surface_set_target(png_surface) { | |
| draw_clear_alpha(#ffffff, 0); | |
| gpu_set_blendenable(false); | |
| draw_sprite(sprite_asset, frame_number, 0, 0); | |
| gpu_set_blendenable(true) | |
| surface_reset_target(); | |
| } | |
| var surface_byte_size = png_width * png_height * 4; | |
| var surface_buffer = buffer_create(surface_byte_size, buffer_fixed, 1); | |
| buffer_get_surface(surface_buffer, png_surface, 0); | |
| var filtered_buffer_size = surface_byte_size + png_height; | |
| var filtered_buffer = buffer_create(filtered_buffer_size, buffer_fixed, 1); | |
| var scanline_stride = png_width * 4; | |
| for (var scanline = 0; scanline < png_height; scanline = scanline + 1) { | |
| buffer_write(filtered_buffer, buffer_u8, 0); | |
| buffer_copy(surface_buffer, scanline * scanline_stride, scanline_stride, filtered_buffer, buffer_tell(filtered_buffer)); | |
| buffer_seek(filtered_buffer, buffer_seek_relative, scanline_stride); | |
| } | |
| var compressed_filtered_png_buffer = buffer_compress(filtered_buffer, 0, filtered_buffer_size); | |
| buffer_delete(filtered_buffer); | |
| buffer_delete(surface_buffer); | |
| surface_free(png_surface); | |
| //write idat | |
| var compressed_filtered_png_buffer_size = buffer_get_size(compressed_filtered_png_buffer); | |
| buffer_write_u32_backwards(png_buffer, compressed_filtered_png_buffer_size); | |
| crc_begin = buffer_tell(png_buffer); | |
| buffer_write(png_buffer, buffer_text, "IDAT"); | |
| var copy_stride_begin = buffer_tell(png_buffer); | |
| buffer_resize(png_buffer, copy_stride_begin + compressed_filtered_png_buffer_size); | |
| buffer_copy(compressed_filtered_png_buffer, 0, compressed_filtered_png_buffer_size, png_buffer, copy_stride_begin); | |
| buffer_seek(png_buffer, buffer_seek_start, copy_stride_begin + compressed_filtered_png_buffer_size); | |
| buffer_delete(compressed_filtered_png_buffer); | |
| crc_length = buffer_tell(png_buffer) - crc_begin; | |
| crc_hash = buffer_crc32(png_buffer, crc_begin, crc_length) ^ 0xffffffff; | |
| buffer_write_u32_backwards(png_buffer, crc_hash); | |
| //write iend | |
| buffer_write(png_buffer, buffer_u32, 0); | |
| crc_begin = buffer_tell(png_buffer); | |
| buffer_write(png_buffer, buffer_text, "IEND"); | |
| crc_length = buffer_tell(png_buffer) - crc_begin; | |
| crc_hash = buffer_crc32(png_buffer, crc_begin, crc_length) ^ 0xffffffff; | |
| buffer_write_u32_backwards(png_buffer, crc_hash); | |
| var final_buffer_size = buffer_tell(png_buffer) | |
| buffer_resize(png_buffer, final_buffer_size); | |
| var png_base64 = buffer_base64_encode(png_buffer, 0, final_buffer_size); | |
| buffer_delete(png_buffer); | |
| return $"data:image/png;base64,{png_base64}" | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
GOAT