【问题标题】:C SDL2 - Selecting part of an image and then zooming inC SDL2 - 选择图像的一部分然后放大
【发布时间】:2018-05-25 21:57:48
【问题描述】:

所以,我有一张使用 SDL2 在窗口中打开的图像。我想为图像实现一个缩放功能,如下所示:我单击图像的两个点,然后用这些点作为对角制作一个矩形。然后我复制矩形并更新窗口以显示我选择的图像的一部分,这个新图像的宽度和高度比我选择的矩形更大,因为它将是整个窗口的高度和宽度. 我可以检测到鼠标点击,并通过鼠标点击计算矩形的左上角在 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 位置的代码,但我真的不能再进一步了。

【问题讨论】:

  • 如何绘制(SDL 窗口表面、SDL_Renderer、...)?
  • @keltar 你现在明白了吗?
  • 您可以分配所需大小的表面并使用SDL_RenderReadPixels 获取源像素,然后创建窗口/渲染器,并将表面推送到第二个渲染器上的纹理。
  • @keltar 你能用代码解释一下吗?比如说,我要缩放的矩形从 x = 50 px 和 y = 50 px 开始,宽度为 50 像素,高度为 70 像素。我向用户展示的图像的宽度 (IMAGE_WIDTH)1024 和高度 (IMAGE_HEIGHT) 515。我该怎么办?

标签: c zooming sdl sdl-2


【解决方案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 事件处理程序中,它创建第二个窗口/渲染器/纹理(不是它的最佳位置),然后如果存在,它会渲染第二个窗口。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-30
    • 2014-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多