←3DSのHBL用アプリ開発 トップへ

ビットマップファイルを開いてフレームバッファに描画する

SDカード上に置いたビットマップファイルを開いてフレームバッファに描画します。

最終更新:2017/09/23




はじめに


前回、フレームバッファ上に点を打つ方法を説明しましたが、今回はビットマップ画像を描画してみようと思います。



準備


Kazutoshi Ando 氏の「C言語による画像処理プログラミング」のヘッダファイルとソースファイルをソースフォルダーにダウンロードします。
そして、描画させたい画像は、右に90度回転させた状態で実機で実行する場合は実行する3dsxがある同じフォルダに、Citraで実行する場合は「sdmc」フォルダ直下に入れます。(AppData>Roaming>Citra>sdmcにあると思います)

BMP画像を読み込む


※上でダウンロードした「bmp.h」をインクルードしておきます。
まず、画像データを格納する構造体(img)変数へのポインタを用意し、mallocで確保します。
img *img1;
img1 = (img *)malloc(sizeof(img));

次に、画像を読み込みます。 ReadBmp関数で読み込みます。
void ReadBmp(char *filename, //ファイル名
     img *imgp //img構造体
    );

ファイルが存在しない場合は、終了されます。(bmp.c)

BMP画像を描画する


gfxGetFramebuffer関数でフレームバッファを取得しますが、このバッファはデーターが連続しているので、画像サイズに合わせて適切に描画する必要があります。
//mx,my=3DS画面の解像度(xとyが入れ替わっていることに注意)
unsigned int x = 0, y = 0, mx = 240, my = 400;
u8 brg[3] = { 0,0,0 };
for (int i = 0; i <= mx*my; i++) {
    if ((x < (img1->width)) && (y < (img1->height))) { //点を打って良いかの判定
        brg[2] = img1->data[y][x].r;
        brg[1] = img1->data[y][x].g;
        brg[0] = img1->data[y][x].b;
    } else { //背景
        brg[0] = 0;
        brg[1] = 0;
        brg[2] = 0;
    }
    memcpy(fb + i * 3, brg, sizeof(brg)); //バッファにコピー
    x++;
    if (x >= mx) {
        x = 0;
        y++;
    }
}


サンプル


STARTで終了
#include <3ds.h>
#include <stdio.h>
#include <string.h>
#include "bmp.h"

int main(int argc, char **argv)
{
    gfxInitDefault();
    gfxSetDoubleBuffering(GFX_TOP, false);
    u8* fb = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL);
    img *img1;
    img1 = (img *)malloc(sizeof(img));
    ReadBmp("img.bmp", img1); //画像読み込み

    //mx,my=3DS画面の解像度(xとyが入れ替わっていることに注意)
    unsigned int x = 0, y = 0, mx = 240, my = 400;
    u8 brg[3] = { 0,0,0 };
    for (int i = 0; i <= mx*my; i++)
    {
        if ((x < (img1->width)) && (y < (img1->height))) { //点を打って良いかの判定
            brg[2] = img1->data[y][x].r;
            brg[1] = img1->data[y][x].g;
            brg[0] = img1->data[y][x].b;
        } else { //背景
            brg[0] = 0;
            brg[1] = 0;
            brg[2] = 0;
        }
        memcpy(fb + i * 3, brg, sizeof(brg)); //バッファにコピー
        x++;
        if (x >= mx) {
            x = 0;
            y++;
        }
    }
    // メインループ
    while (aptMainLoop())
    {
        hidScanInput();
        u32 kDown = hidKeysDown();
        if (kDown & KEY_START) break;
        gfxFlushBuffers();
        gfxSwapBuffers();
        gspWaitForVBlank();
    }
    gfxExit();
    return 0;
}

●スクリーンショット
結果

●使った画像
bmp形式なので直接DLできます。(コピーライトが付いているが...)
使った画像
画像は999x999以内であればどの大きさでも描画できます。
(bmp.hの「MAXWIDTH」「MAXHEIGHT」で変更も出来ます。)




[前へ] [次へ]

(C)2017 InoueSoftware / 無断転載禁止