bugfix> c > 投稿

そのため、SDL2を使用してウィンドウで開く画像があります。次のように機能する画像のズーム機能を実装します。画像の2つのポイントをクリックし、それらのポイントを対角として長方形を作成します。次に、長方形のコピーを作成し、ウィンドウを更新して、選択した画像の一部を表示します。この新しい画像は、ウィンドウ全体の高さと幅になるため、選択した長方形よりも幅と高さが大きくなります。 。 マウスクリックを検出でき、マウスクリックからx座標とy座標の長方形の左上隅を計算します。ただし、これらの長方形のピクセルのコピーを作成する方法も、ウィンドウにズームされた部分を表示するようにする方法もわかりません。私は多くのことをグーグルしてきましたが、どの関数を使用するのか、自分のコードをどのようにコーディングするのかわかりません。このような関数はどのように書くのでしょうか?

ここに私がこれまでに持っているものがあります。拡大したい画像は「map.jpg」です

SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window *window = NULL;
window = SDL_CreateWindow("WarmingUp", TOP_LEFT_CORNER_X,
                          TOP_LEFT_CORNER_Y, IMAGE_WIDTH, IMAGE_HEIGHT, 0);
if(window == NULL){
    printf("Erro a abrir janela gráfica\n");
    exit(EXIT_FAILURE);
}
SDL_Renderer *renderer = NULL;
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL){
    printf("Erro a criar renderer\n");
    exit(EXIT_FAILURE);
}
SDL_Surface *jpgSurface = NULL;
jpgSurface = IMG_Load("map.jpg");
if(jpgSurface == NULL){
    printf("Erro a abrir imagem\n");
    exit(EXIT_FAILURE);
}
SDL_Texture *jpgTexture = NULL;
jpgTexture = SDL_CreateTextureFromSurface(renderer, jpgSurface);
if(jpgTexture == NULL){
    printf("Erro a criar superfície através de imagem\n");
    exit(EXIT_FAILURE);
}
SDL_FreeSurface(jpgSurface);
SDL_Event e;
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, jpgTexture, NULL, NULL);    
while(!quit){
    while(SDL_PollEvent(&e)){
        if(e.type == SDL_QUIT)
            quit = 1;
        SDL_RenderPresent(renderer);
        SDL_Delay(15);
SDL_DestroyTexture(jpgTexture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();

私は私の while &eventloop でマウス操作を行うことを知っています if ( event.type == SDL_MOUSEBUTTONUP ) を確認する必要があります 、また、トリミングする必要のある長方形の左上隅のxおよびy位置を計算するコードを表示することもできますが、これ以上先へ進むことはできません。

回答 1 件
  • 質問から修正されたコードは次のとおりです。

    #include <stdio.h>
    #include <SDL.h>
    #include <SDL_image.h>
    #define IMAGE_WIDTH 1024
    #define IMAGE_HEIGHT 768
    int main(int argc, char **argv) {
        (void)argc, (void)argv;
        int quit = 0;
        SDL_Init(SDL_INIT_EVERYTHING);
        SDL_Window *window = NULL;
        window = SDL_CreateWindow("WarmingUp",
                SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                IMAGE_WIDTH, IMAGE_HEIGHT, 0);
        if(window == NULL){
            printf("Erro a abrir janela gráfica\n");
            exit(EXIT_FAILURE);
        }
        SDL_Renderer *renderer = NULL;
        renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
        if (renderer == NULL){
            printf("Erro a criar renderer\n");
            exit(EXIT_FAILURE);
        }
        SDL_Surface *jpgSurface = NULL;
        jpgSurface = IMG_Load("map.jpg");
        if(jpgSurface == NULL){
            printf("Erro a abrir imagem\n");
            exit(EXIT_FAILURE);
        }
        SDL_Texture *jpgTexture = NULL;
        jpgTexture = SDL_CreateTextureFromSurface(renderer, jpgSurface);
        if(jpgTexture == NULL){
            printf("Erro a criar superfície através de imagem\n");
            exit(EXIT_FAILURE);
        }
        SDL_FreeSurface(jpgSurface);
        SDL_Event e;
        // rectangle to upscale in second window
        const SDL_Rect srcrect = {600, 500, 250, 250};
        SDL_Window *second_window = NULL;
        SDL_Renderer *second_renderer = NULL;
        SDL_Texture *magnified_fragment_texture = NULL;
        while(!quit){
            while(SDL_PollEvent(&e)){
                if(e.type == SDL_QUIT ||
                        (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE)) {
                    quit = 1;
                } else if(e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_t &&
                        !second_window) {
                    // create empty surface of adequate size
                    SDL_Surface *const surf = SDL_CreateRGBSurface(0, srcrect.w, srcrect.h, 32,
                            0xff000000, 0xff0000, 0xff00, 0xff);
                    SDL_FillRect(surf, NULL, 0);
                    // copy pixels
                    SDL_RenderReadPixels(renderer, &srcrect, SDL_PIXELFORMAT_RGBA8888,
                            surf->pixels, surf->pitch);
                    // error checking should be done...
                    second_window = SDL_CreateWindow("mag",
                            SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                            srcrect.w*2, srcrect.h*2, 0);
                    second_renderer = SDL_CreateRenderer(second_window, -1, SDL_RENDERER_ACCELERATED);
                    magnified_fragment_texture = SDL_CreateTextureFromSurface(second_renderer, surf);
                    SDL_FreeSurface(surf);
                }
            }
            SDL_RenderClear(renderer);
            SDL_RenderCopy(renderer, jpgTexture, NULL, NULL);    
            SDL_RenderPresent(renderer);
            if(second_renderer) {
                const SDL_Rect dstrect = {0, 0, srcrect.w*2, srcrect.h*2};
                SDL_RenderClear(second_renderer);
                // RenderCopy scales texture to destination rect
                SDL_RenderCopy(second_renderer, magnified_fragment_texture, NULL, &dstrect);
                SDL_RenderPresent(second_renderer);
            }
            SDL_Delay(15);
        }
        SDL_DestroyTexture(jpgTexture);
        SDL_DestroyRenderer(renderer);
        SDL_DestroyWindow(window);
        SDL_Quit();
        return 0;
    }
    
    

    keypressイベントハンドラーでは、2番目のウィンドウ/レンダラー/テクスチャ(最適な場所ではない)を作成し、後で2番目のウィンドウが存在する場合はそれをレンダリングします。

あなたの答え