1

我需要使用 C 编程创建一个简单的数据库来存储图像。然后我如何使用数据库将图像一张一张地提供给另一个应用程序。每个图像都有一个 ID。如果任何图像与我的应用程序需要匹配。其对应的 ID 必须作为输出打印。

我需要为大约 350 张图像创建数据库。我的主应用程序是用 C 编写的。那么任何人都可以帮助我如何创建数据库以及如何将其与主应用程序链接?

4

1 回答 1

2

最简单的方法是将作为 BLOB 存储在sqlite db 中,它将作为单个 .c 文件集成到您的项目中。请参阅示例 C 文件,该文件演示了访问 blob 的两种不同方式。一种使用绑定,一种使用 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 回答