• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Legacy GM [SOLVED]Check if an image is to large to load

W

Wraithious

Guest
Hello, in my project I'm getting an image from the player like this:
Code:
///Load normal sized images
if(mouse_x>96 && mouse_x<144 && mouse_y>0 && mouse_y<32 && global.progress=0 && canpress=1) {
    global.pic1 = get_open_filename("Image file|*.png;*.jpg;*.gif;*.tif", "");
    if((string_pos(".png", string(global.pic1))|| string_pos(".PNG", string(global.pic1)))||(string_pos(".jpg", string(global.pic1)||
    string_pos(".JPG", string(global.pic1))|| string_pos(".gif", string(global.pic1))|| string_pos(".tif", string(global.pic1))|| string_pos(".TIF", string(global.pic1))))) {
        sprite_replace(sourceImage,global.pic1,1,0,0,0,0);
    }
    global.progress=1;
    x=0;
    y=0;
    canpress=0;
    imgNum=0;
    alarm[0]=15;
}
which is fine, BUT if the image is larger than 8192 x 8192 I want to switch to another way of loading the image, such as creating a buffer to get a portion of the image, then again use the buffer to start off where it left off on the image and get the next portion of the image etc.. To be specific here I'm dealing with satelite images that some (but not all) are as large as 16384 x 16384 So the image would have to be chunked into 4 seperate images.

So my question is, How can I determine BEFORE attempting to get the image what the size of the image is? because loading larger than 8192 x 8192 images crashes the game with an out of memory error (as expected that it should), thanks for any help you can give
 
W

Wraithious

Guest
I should also post what I tried, altho as I said before it gives an out of memory exception and crashes the game, the image size was 16384x16384 (normal image size works fine as expected) :
Code:
///Load Image from file
if(mouse_x>96 && mouse_x<144 && mouse_y>0 && mouse_y<32 && global.progress=0 && canpress=1) {
    var file;
    var sur2;
    var chunkSize = 0;
    global.pic1 = get_open_filename("Image file|*.png;*.jpg;*.gif;*.tif", "");// get the requested image's address
    file = file_bin_open(global.pic1, 0);
    global.filesize = file_bin_size(file);//get the size of the image
    show_debug_message("Got file size: "+string(global.filesize));
    chunks = ceil(global.filesize / 268435456);//get the number of images to split the original image if file size > 16384 * 16384 * 8bit / 8
    for(var i=0;i<chunks;i+=1;) {
        if i<chunks chunkSize[i]=8192;//all but the last image chunk will be max allowable size in pixels
        if i==chunks chunkSize[i]=sqrt(global.filesize mod 268435456);//last image's height is the size of the square root mod of full image size to max allowable image size
        show_debug_message("Image"+string(i)+" size: 8192 x "+string(chunkSize[i]));
    }
    file_bin_close(file);
    if((string_pos(".png", string(global.pic1))|| string_pos(".PNG", string(global.pic1)))||(string_pos(".jpg", string(global.pic1)|| string_pos(".JPG", string(global.pic1))
    || string_pos(".gif", string(global.pic1))|| string_pos(".tif", string(global.pic1))|| string_pos(".TIF", string(global.pic1))))) {
    //Load normal sized image
        if(global.filesize <= 268435456) {
            sprite_replace(sourceImage0,global.pic1,1,0,0,0,0);// image is at or below max size, load it and finish.
        }
        //Load huge image into seperate images
        if(global.filesize > 268435456) {// image needs to be chunked into smaller images
            room_speed = fps_real;
            var buffers=0;
            repeat(chunks) {
                file = file_bin_open(global.pic1,0);
                buff = buffer_create(268435456, buffer_fixed, 1);
                show_debug_message("buffer for image chunk "+string(buffers)+" created.");
                for(var i=0;i<((buffers * 268435456)+268435456);i++;) {
                    if i>= buffers * 268435456 buffer_write(buff, buffer_u8, file_bin_read_byte(file));
                }
                file_bin_close(file);
                buffer_set_surface(buff, sur2, 0, 0, 0);
                var hold = sprite_create_from_surface(sur2,0,0,8192,chunkSize[buffers],0,0,0,0);
                sprite_assign(asset_get_index("sourceImage"+string(buffers)),hold);
                show_debug_message("sprite image chunk "+string(buffers)+" assigned.");
                buffer_delete(buff);
                buffers+=1;
            }
        }
        //image(s) loading completed
        room_speed = 30;
        global.progress=1;
        x=0;
        y=0;
        canpress=0;
        imgNum=0;
        alarm[0]=15;//can't press button again until the cpu cools off a little haha
    }
}
And this is the error message in the compile window:
Code:
Got file size: 194216710
Image0 size: 8192 x 8192
Out of Memory allocating zu bytes
It gets as far as line 15 on the first iteration of what should be 4 iterations and breaks before even trying to do anything with the file

Something else I noticed is that the file size shown in the debug message is much smaller than what it should be, the file size in KB should be (width in pixels * height in pixels * bit depth) / 8 right? well the bit depth in my huge image is 8, so that cancells out the divisor, so the size in KB should be reported as 268435456, and since it's not then that's why it crashed because the image is twice as big as gamemakers limit.
So the question of this topic still is, how do you get the size of the image before trying to load it?
 
Last edited by a moderator:
W

Wraithious

Guest
SOLVED
it was an error in my math, I was using the image size of the huge image as my max alowable image size in the above code instead of the max size gamemaker has which is 67,107,864. After also fixing my undefined surface error I also had it works now (well kinda, the image is all black but I may have to tweek the buffer some or convert to base64 buffer)
 
Top