Mengubah Ukuran dan Mengoptimalkan Gambar

Dalam SDL, ada dua cara yang biasa digunakan untuk menampilkan atau mencetak gambar ke dalam permukaan / surface. pertama adalah SDL_BlitSurface, dan yang kedua adalah SDL_BlitScaled. Perbedaannya adalah pada penggunaan parameter ke-4. Walaupun sama-sama menggunakan SDL_Rect untuk menentukan bagian gambar yang ditampilkan dan posisinya, tapi pada SDL_BlitSurface tidak akan ada perubahan ukuran gambar karena parameter keempatnya mengabaikan nilai w(width) dan h(height). 
 
Pada SDL_BlitScaled, gambar bisa diubah ukurannya dengan nilai w dan h dari argumen pada parameter ke-4. Kecepatan untuk menampilkan gambar dari SDL_BlitSurface tentu saja akan lebih cepat daripada SDL_BlitScaled karena proses yang dibutuhkan lebih sederhana. Mana yang akan kita gunakan? Kita akan menggunakannya sesuai dengan kebutuhan.
Untuk mencoba penerapan function SDL_BlitScaled, kita akan menampilkan gambar dengan nama "Codelogi.bmp" dengan dua ukuran dalam kode program berikut ini.
#include <SDL2/SDL.h>

int main( int argc, char* args[] ){
    SDL_Window* window = NULL;
    SDL_Event evt;

    SDL_Surface* screenSurface = NULL;

    if( SDL_Init( SDL_INIT_VIDEO ) < 0 ){
        printf( "Error: %s\n", SDL_GetError() );
    }else{
        window = SDL_CreateWindow( "SDLku", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN );
        if( window == NULL ){
            printf( "Error : %s", SDL_GetError() );
        }else{
            screenSurface = SDL_GetWindowSurface( window );

            SDL_FillRect( screenSurface, NULL, SDL_MapRGB( screenSurface->format, 0xFF, 0xFF, 0xFF) );
            SDL_Surface *tmp=SDL_LoadBMP("Codelogi.bmp");
            if(tmp){
                SDL_Surface *bmp=SDL_ConvertSurface(tmp, screenSurface->format, 0);
                SDL_Rect rct, rcd;
                SDL_FreeSurface(tmp);
                rct.x=bmp->w/2;
                rct.y=0;
                rct.w=bmp->w;
                rct.h=bmp->h;

                rcd.x=0;
                rcd.y=0;
                rcd.w=bmp->w*2;
                rcd.h=bmp->h*2;
                if(bmp){
                    while(evt.type!=SDL_QUIT){
                        while(SDL_PollEvent(&evt)){
                            SDL_BlitScaled(bmp, &rct, screenSurface, &rcd);
                            SDL_BlitSurface(bmp, &rct, screenSurface, &rcd);
                            SDL_UpdateWindowSurface( window );
                        }
                    }
                    SDL_FreeSurface(bmp);
                }
            }
        }
    }

    SDL_DestroyWindow( window );
    SDL_Quit();

    return 0;
}

Dalam program akan  terlihat dua gambar yang terpotong pada posisi yang sama walaupun ukurannya berbeda. Itu terjadi karena kita mengubah nilai x pada argumen parameter pertama sehingga gambar yang ditampilkan hanya ditampilkan dari bagian tengah gambar. Selain itu, gambar yang pertama ditampilkan menggunakan SDL_BlitScaled sehingga ukurannya 2 kali lebih besar karena nilai w dan h dari variabel rcd adalah 2 kali ukuran gambar. Sekalipun variabel-variabel yang digunakan pada function adalah variabel yang sama, tapi hasilnya berbeda karena ada anggota yang diabaikan dari variabel rcd, yaitu w dan h.

Mengoptimalkan permukaan gambar
Jika pada program yang digunakan untuk mengedit foto ada layer, dalam SDL ada surface atau variabel bertipe SDL_Surface yang bisa digunakan untuk menyimpan gambar sementara sebelum ditampilkan. Tiap surface bisa punya format gambar yang berbeda-beda. 
 
Sebelum "disatukan" dalam surface pada window atau surface lain, setiap surface akan disesuaikan formatnya supaya sama dengan format dari surface tujuan. Misalnya, jika surface tujuan adalah 32 bit dan surface asal adalah 24 bit maka surface asal akan diubah dulu menjadi 32 bit sesuai surface tujuan. Walaupun diubah, tapi perubahan tersebut tidak benar-benar disimpan secara permanen sehingga tiap kali kita perlu menampilkan gambar akan ada proses tambahan yang bisa memperlambat program.

Untuk surface kosong yang akan kita buat, kita bisa menentukan formatnya, tapi, saat kita memuat gambar dengan SDL_LoadBMP atau semacamnya, formatnya akan menyesuaikan dengan gambar yang dimuat.
#include <SDL2/SDL.h>

int main( int argc, char* args[] ){
    SDL_Window* window = NULL;
    SDL_Event evt; 
    SDL_Surface* screenSurface = NULL;

    if( SDL_Init( SDL_INIT_VIDEO ) < 0 ){
        printf( "Error: %s\n", SDL_GetError() );
    }else{
        window = SDL_CreateWindow( "SDLku", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_SHOWN );
        if( window == NULL ){
        printf( "Error : %s", SDL_GetError() );
    }else{
        screenSurface = SDL_GetWindowSurface( window );

        SDL_FillRect( screenSurface, NULL, SDL_MapRGB( screenSurface->format, 0xFF, 0xFF, 0xFF) );
        SDL_Surface *tmp=SDL_LoadBMP("Codelogi.bmp");
        if(tmp){
            SDL_Surface *bmp=SDL_ConvertSurface(tmp, screenSurface->format, 0);
            SDL_FreeSurface(tmp);
            if(bmp){
                    while(evt.type!=SDL_QUIT){
                        while(SDL_PollEvent(&evt)){
                            SDL_BlitSurface(bmp, 0, screenSurface, 0);
                            SDL_UpdateWindowSurface( window );
                        }
                    }
                    SDL_FreeSurface(bmp);
                }
            }
        }
    }

    SDL_DestroyWindow( window );
    SDL_Quit();

    return 0;
}
SDL_ConvertSurface akan menghasilkan SDL_surface yang baru, jadi kita seharusnya menghapus surface yang sudah kita convert dengan SDL_FreeSurface dengan tujuan untuk mengosongkan memori yang sudah tidak digunakan lagi.
 
Kalau kalian malas mengetik, kalian bisa mendownload kode programnya di sini.