Skip to content

Instantly share code, notes, and snippets.

@attic-stuff
Last active August 24, 2025 16:25
Show Gist options
  • Select an option

  • Save attic-stuff/d6d3f27a1a9a8d46f3dd79181d9e95c7 to your computer and use it in GitHub Desktop.

Select an option

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
/**
* 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}"
}
@katsaii
Copy link

katsaii commented Aug 24, 2025

GOAT

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment