c++ - 如何使用C编程创建图像数据库?

标签 c++ c database linux image-processing

<分区>

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

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

最佳答案

最简单的方法是将 BLOB 存储在 sqlite 中db 集成为项目中的单个 .c 文件。请参阅示例 C 文件,该文件演示了访问 blob 的两种不同方式。一种使用绑定(bind),一种使用 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 与图像一起存储,只需在同一个表中创建另一列。

关于c++ - 如何使用C编程创建图像数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19132208/

相关文章:

共享库中具有全局状态的 C++ 头文件

c++ - if/else 在什么阶段变得比 switch case 更好?可以?

MySQL:如何查询父子关系?

mysql - 高级 mysql 查询,它对结果集上的特定记录进行排序,而不考虑其默认排序?

c++ - 在现有数据结构上使用BGL算法(作为 vector <Object *>的边和顶点)需要什么?

c++ - 重定向 APPCRASH 转储(或将其关闭)

c - 将 char 变量传递给数组中的下一个值 - C

c - "expected ' 字符 * ' but argument is of type ' 字符 ' "- 回文 + 反向

c - C中的回文问题

c# - 在内存中缓存数据库表