URLから画像ファイルを開ける様に

このコミットが含まれているのは:
守矢諏訪子 2024-04-07 10:36:43 +09:00
コミット bc8d609230
4個のファイルの変更160行の追加47行の削除

ファイルの表示

@ -1,3 +1,6 @@
# 0.4.0
* URLから画像ファイルを開ける様に
# 0.3.0
* 負荷をすくなくするために画面の更新を減らした (たかしさん)

ファイルの表示

@ -1,14 +1,16 @@
NAME=mivfx
VERSION=0.3.0
VERSION=0.4.0
# Linux、Haiku、かIllumos = /usr、FreeBSDかOpenBSD = /usr/local、NetBSD = /usr/pkg
PREFIX=/usr
PREFIX=/usr/local
CC=cc
FILES=main.c
CFLAGS=-Wall -Wextra -g
LDFLAGS=-lSDL2 -lSDL2_image
LIBS=-lSDL2 -lSDL2_image -lcurl
LDFLAGS=-L${PREFIX}/lib
CPPFLAGS=-I${PREFIX}/include
all:
${CC} ${CFLAGS} -o ${NAME} ${FILES} ${LDFLAGS}
${CC} ${CFLAGS} ${CPPFLAGS} -o ${NAME} ${FILES} ${LDFLAGS} ${LIBS}
clean:
rm -f ${NAME}

ファイルの表示

@ -1,2 +1,53 @@
# mivfx - minimarist image view for x
ミニマリストな画像ビューアー
# インストールする方法
## OpenBSD
```sh
doas pkg_add sdl2 sdl2_image curl
make
doas make install
```
## FreeBSD
```sh
doas pkg install sdl2 sdl2_image curl
make
doas make install
```
## NetBSD
```sh
doas pkgin install SDL2-2.28.5 SDL2_image curl
make PREFIX=/usr/pkg
doas make install PREFIX=/usr/pkg
```
## CRUX
```sh
doas prt-get depinst libsdl2 sdl2_image curl
make PREFIX=/usr
doas make install PREFIX=/usr
```
## Void Linux
```sh
doas xbps-install -S SDL2 SDL2_image curl
make PREFIX=/usr
doas make install PREFIX=/usr
```
## Artix Linux
```sh
doas pacman -S sdl2 sdl2_image curl
make PREFIX=/usr
doas make install PREFIX=/usr
```
## Devuan GNU/Linux
```sh
doas apt install libsdl2-dev libsdl2-image-dev libcurl4
make PREFIX=/usr
doas make install PREFIX=/usr
```

215
main.c
ファイルの表示

@ -2,94 +2,40 @@
#include <SDL2/SDL_image.h>
#include <stdio.h>
#include <stdbool.h>
#include <curl/curl.h>
#define DELAY_MS 50
int main(int argc, char* argv[]) {
if (argc < 2) {
printf("使用方法: %s <画像ファイル>\n", argv[0]);
return 1;
SDL_Window* window = NULL;
SDL_Renderer* renderer = NULL;
SDL_Texture* texture = NULL;
bool quit = false;
bool dlfile(const char* url, const char* filename) {
CURL* curl = curl_easy_init();
if (!curl) {
return false;
}
SDL_Window* window = NULL;
SDL_Renderer* renderer = NULL;
SDL_Texture* texture = NULL;
// SDL2とSDL2_imageの初期設定
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("SDLを初期設定出来なかった%s\n", SDL_GetError());
return 1;
FILE* file = fopen(filename, "wb");
if (!file) {
return false;
}
if (!(IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG)) {
printf("SDL_imageを初期設定出来なかった%s\n", SDL_GetError());
SDL_Quit();
return 1;
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, file);
CURLcode res = curl_easy_perform(curl);
fclose(file);
if (res != CURLE_OK) {
remove(filename);
return false;
}
// 画像の読込
SDL_Surface* imgsurface = IMG_Load(argv[1]);
if (imgsurface == NULL) {
printf("画像の読込に失敗:%s\n", IMG_GetError());
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
return true;
}
// 画像の大きさの受取
int imgWidth = imgsurface->w;
int imgHeight = imgsurface->h;
/* float aspectRatio = (float)imgWidth / imgHeight; */
// 画面の大きさの受取
SDL_DisplayMode DM;
SDL_GetCurrentDisplayMode(0, &DM);
int screenWidth = DM.w;
int screenHeight = DM.h;
// 画像は50x50以下じゃ駄目
int minWidth = 50;
int minHeight = 50;
if (imgWidth < minWidth) imgWidth = minWidth;
if (imgHeight < minHeight) imgHeight = minHeight;
// ウィンドウの大きさの設定
int windowWidth = (imgWidth > screenWidth) ? screenWidth : imgWidth;
int windowHeight = (imgHeight > screenHeight) ? screenHeight : imgHeight;
// ウィンドウの作成
SDL_SetHint(SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT, "1");
window = SDL_CreateWindow("mivfx", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, windowWidth, windowHeight, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
if (window == NULL) {
printf("ウィンドウの作成に失敗:%s\n", SDL_GetError());
SDL_Quit();
return 1;
}
// レンダーの作成
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL) {
printf("レンダーの作成に失敗:%s\n", SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
texture = SDL_CreateTextureFromSurface(renderer, imgsurface);
SDL_FreeSurface(imgsurface);
if (texture == NULL) {
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
// メインループ
SDL_Event e;
bool quit = false;
while (!quit) {
// イベント
while (SDL_PollEvent(&e) != 0) {
void windowevent(SDL_Event e) {
if (e.type == SDL_QUIT) {
quit = true;
} else if (e.type == SDL_WINDOWEVENT && e.window.event == SDL_WINDOWEVENT_RESIZED) {
@ -126,6 +72,114 @@ int main(int argc, char* argv[]) {
// 画面の更新
SDL_RenderPresent(renderer);
}
}
int main(int argc, char* argv[]) {
if (argc < 2) {
printf("使用方法: %s <画像ファイル>\n", argv[0]);
return 1;
}
// SDL2とSDL2_imageの初期設定
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("SDLを初期設定出来なかった%s\n", SDL_GetError());
return 1;
}
if (!(IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG)) {
printf("SDL_imageを初期設定出来なかった%s\n", SDL_GetError());
SDL_Quit();
return 1;
}
const char* imgfile = argv[1];
// URLの場合、仮にダウンロードして
bool isurl = strncmp(imgfile, "http://", 7) == 0 ||
strncmp(imgfile, "https://", 8) == 0;
char tmpname[] = "/tmp/netimg.png";
if (isurl) {
if (!dlfile(imgfile, tmpname)) {
printf("画像をダウンロードに失敗。URL: %s\n", imgfile);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
imgfile = tmpname;
}
// 画像の読込
SDL_Surface* imgsurface = IMG_Load(imgfile);
if (imgsurface == NULL) {
printf("画像の読込に失敗:%s\n", IMG_GetError());
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
// 画像の大きさの受取
int imgWidth = imgsurface->w;
int imgHeight = imgsurface->h;
/* float aspectRatio = (float)imgWidth / imgHeight; */
// 画面の大きさの受取
SDL_DisplayMode DM;
SDL_GetCurrentDisplayMode(0, &DM);
int screenWidth = DM.w;
int screenHeight = DM.h;
// 画像は50x50以下じゃ駄目
int minWidth = 50;
int minHeight = 50;
if (imgWidth < minWidth) imgWidth = minWidth;
if (imgHeight < minHeight) imgHeight = minHeight;
// ウィンドウの大きさの設定
int windowWidth = (imgWidth > screenWidth) ? screenWidth : imgWidth;
int windowHeight = (imgHeight > screenHeight) ? screenHeight : imgHeight;
// ウィンドウの作成
SDL_SetHint(SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT, "1");
window = SDL_CreateWindow(
"mivfx",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
windowWidth,
windowHeight,
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE
);
if (window == NULL) {
printf("ウィンドウの作成に失敗:%s\n", SDL_GetError());
SDL_Quit();
return 1;
}
// レンダーの作成
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL) {
printf("レンダーの作成に失敗:%s\n", SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
texture = SDL_CreateTextureFromSurface(renderer, imgsurface);
SDL_FreeSurface(imgsurface);
if (texture == NULL) {
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
// メインループ
SDL_Event e;
while (!quit) {
// イベント
while (SDL_PollEvent(&e) != 0) {
windowevent(e);
}
// 休ませる
@ -133,6 +187,9 @@ int main(int argc, char* argv[]) {
}
// 掃除
if (isurl) {
remove(tmpname);
}
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);