1

画像を保存するために、C プログラミングを使用して単純なデータベースを作成する必要があります。次に、データベースを使用して、画像を 1 つずつ別のアプリケーションにフィードする方法について説明します。各イメージには 1 つの ID があります。画像のいずれかが私のアプリケーションのニーズと一致する場合。対応する ID を出力として出力する必要があります。

約 350 枚の画像のデータベースを作成する必要があります。私のメイン アプリケーションは C で書かれています。データベースの作成方法とメイン アプリケーションとのリンク方法を教えてください。

4

1 に答える 1

2

最も簡単な方法は、プロジェクトに単一の .c ファイルとして統合されるsqlite db にBLOB として格納することです。BLOB にアクセスする 2 つの異なる方法を示す C ファイルの例を参照してください。1 つはバインドを使用し、もう 1 つは BLOB API を使用します。

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <sys/time.h>
#include <unistd.h>
#include <libgen.h>
#include "sqlite3.h"

sqlite3 *db;

int error(char *msg) {
    fprintf(stderr, "ERROR: %s\n", msg);
    if(db)
        sqlite3_close(db);
    exit(1);
}

int gettype(char **imgtype, int columns, char **colval, char **colname) {
    int col;

    if(columns!=1)
        return 1;

    snprintf((char *)imgtype, 4, "%s", colval[0]);

    return 0;
}

int getrowid(sqlite3_int64 *rowid, int columns, char **colval, char **colname) {
    int col;

    if(columns!=1)
        return 1;

    *rowid=(int)strtol(colval[0], NULL, 10);

    return 0;
}

int main(int argc, char **argv) {
    enum { PROG, FUNC, TABLE, NAME };

    sqlite3_blob *dblob;
    char sqlcmd[1024];
    sqlite3_int64 rowid=0;
    sqlite3_stmt *stmt;
    char *zErrMsg=0;

    char filename[1024];
    char outname[1024];
    char imgtype[4];
    FILE *fblob;
    char *blobmem;
    long blobsize;


    if(argc!=4) 
        error("usage: blob <get|put> <table> <filename>");


    if(sqlite3_open(DATABASE, &db)) 
        error((char*)sqlite3_errmsg(db));

    sqlite3_busy_timeout(db, TIMEOUT);


    // using bind api
    if(strcmp(argv[FUNC], "put")==0) {
        snprintf(filename, 1024, "%s", basename(argv[NAME]));
        strtok(filename, ".");
        snprintf(imgtype, 4, "%s", strtok(NULL, "."));

        if(!strlen(imgtype) || !(strcasecmp(imgtype, "gif")==0 || strcasecmp(imgtype, "jpg")==0 || strcasecmp(imgtype, "png")==0))
            error("wrong extension / img type");

        fblob=fopen(argv[NAME], "r");
        if(fblob==NULL) 
            error("file not found");

        fseek(fblob, 0L, SEEK_END);
        blobsize=ftell(fblob);
        if(!blobsize) 
            error("wrong file size");

        blobmem=malloc(blobsize);
        if(!blobmem) 
            error("unable to allocate memory");

        rewind(fblob);
        if(fread(blobmem, blobsize, 1, fblob)!=1) 
            error("unable to read file");
        fclose(fblob);

        snprintf(sqlcmd, 1024, "delete from '%s' where name like '%s';", argv[TABLE], filename);
        if(sqlite3_exec(db, sqlcmd, NULL, NULL, &zErrMsg)!=SQLITE_OK) 
            error(zErrMsg);

        snprintf(sqlcmd, 1024,  "insert into '%s'(name, type, data) values(?, ?, ?);", argv[TABLE]);
        if(sqlite3_prepare_v2(db, sqlcmd, -1, &stmt, 0)!=SQLITE_OK) 
            error((char*)sqlite3_errmsg(db));

        sqlite3_bind_text(stmt, 1, filename, -1, SQLITE_STATIC);
        sqlite3_bind_text(stmt, 2, imgtype, -1, SQLITE_STATIC);
        sqlite3_bind_blob(stmt, 3, blobmem, blobsize, SQLITE_STATIC);

        if(sqlite3_step(stmt)!=SQLITE_DONE) 
            error((char*)sqlite3_errmsg(db));

        if(sqlite3_finalize(stmt)!=SQLITE_OK) 
            error((char*)sqlite3_errmsg(db));

        free(blobmem);

    }
    // using blob api
    else if(strcmp(argv[FUNC], "get")==0) {
        snprintf(filename, 1024, "%s", argv[NAME]);
        strtok(filename, ".");

        snprintf(sqlcmd, 1024, "select rowid from '%s' where name like '%s';", argv[TABLE], filename);
        if(sqlite3_exec(db, sqlcmd, (void *)&getrowid, &rowid, &zErrMsg)!=SQLITE_OK) 
            error(zErrMsg);

        if(!rowid) 
            error("not found");

        snprintf(sqlcmd, 1024, "select type from '%s' where name like '%s';", argv[TABLE], filename);
        if(sqlite3_exec(db, sqlcmd, (void *)&gettype, &imgtype, &zErrMsg)!=SQLITE_OK)
            error(zErrMsg);

        if(!strlen(imgtype) || !(strcasecmp(imgtype, "gif")==0 || strcasecmp(imgtype, "jpg")==0 || strcasecmp(imgtype, "png")==0))
            error("wrong extension / img type");

        if(sqlite3_blob_open(db, "main", argv[TABLE], "data", rowid, 0, &dblob)!=SQLITE_OK) 
            error((char*)sqlite3_errmsg(db));

        blobsize=sqlite3_blob_bytes(dblob);
        if(!blobsize)
            error("image is 0 bytes in size");

        blobmem=malloc(blobsize);
        if(!blobmem)
            error("unable to allocate memory");

        if(sqlite3_blob_read(dblob, blobmem, blobsize, 0)!=SQLITE_OK)
            error("unable to read image");

        sqlite3_blob_close(dblob);

        snprintf(outname, 1024, "%s.%s", filename, imgtype);
        fblob=fopen(outname, "w");
        if(fblob==NULL)
            error("unable to open target file");

        if(fwrite(blobmem, blobsize, 1, fblob)!=1)
            error("unable to write to target file");

        fclose(fblob);
        free(blobmem);
    }
    else 
        error("wrong usage");

    sqlite3_close(db);
    return 0;
}

画像とともに ID を保存するには、同じテーブルに別の列を作成するだけです。

于 2013-10-02T07:54:22.357 に答える