NSImage 到 blob 以及 blob 到 NSImage(SQLite、NSData)

发布于 2024-11-04 08:19:02 字数 3186 浏览 0 评论 0原文

首先,我知道我不应该使用 SQLite 数据库来存储图像,但我只存储非常小的网站图标。

我的问题是,我尝试将这些 favicon 插入数据库(似乎有效),我使用 NSimage< 的 -tiffrepresentation 方法将 favicon 转换为 NSData /code> 然后将其插入到我的数据库中的 blob 列中:

 NSImage *favico = [webview mainFrameIcon];
[appDelegate insertBookmark:[titleField stringValue] url:[urlfield stringValue] data:[favico TIFFRepresentation]]

SQLite 方法如下所示:

-(void)insertBookmark:(NSString *)title url:(NSString *)url data:(NSData *)data
{
    NSData *imagedata = [[NSData alloc]initWithData:data]; 
    sqlite3 *database;
    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
        NSString *query = [NSString stringWithFormat:@"INSERT INTO Bookmarks (title, url, image) VALUES ('%@', '%@', '%@')",title, url, data];
        const char *querychar = [query UTF8String]; 
        sqlite3_stmt *statement; 
        if (sqlite3_prepare_v2(database, querychar, -1, &statement, NULL) == SQLITE_OK)
        {
            int row =  3;
            sqlite3_bind_blob(statement, row, [imagedata bytes], [imagedata length], NULL);
            sqlite3_step(statement);
            sqlite3_finalize(statement);

        }
        else
        {
            NSLog(@"Error"); 
        }

        [databasePath retain]; 
        [databaseName retain]; 
    }
    sqlite3_close(database);
    [imagedata release]; 

}

当我查看数据库时,我在 之间的图像列中获得值(正常? )

现在当我从数据库中提取 blob 并尝试将其放入我的对象中 我在 NSimage 中得到 null:

-(void) readDatabase {
// Setup the database object
sqlite3 *database;

bookmarks = [[NSMutableArray alloc] init];

// Open the database from the users filessytem
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
    // Setup the SQL Statement and compile it for faster access
    const char *sqlStatement = "SELECT * FROM Bookmarks ORDER BY title ASC";
    sqlite3_stmt *compiledStatement;
    if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
        // Loop through the results and add them to the feeds array
        while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
            // Read the data from the result row
            NSString *aTitle = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
            NSString *aUrl = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
            NSData *data = [[NSData alloc] initWithBytes:sqlite3_column_blob(compiledStatement, 3) length:sqlite3_column_bytes(compiledStatement, 3)];
            NSImage *image = [[NSImage alloc]initWithData:data];
            bookmarkObject *bookmark = [[bookmarkObject alloc] initWithName:aTitle url:aUrl favico:image]; 

            [bookmarks addObject:bookmark];
            [bookmark release];
            [data release];
            [image release]; 



        }
    }
    // Release the compiled statement from memory
    sqlite3_finalize(compiledStatement);
    sqlite3_close(database); 
    [databasePath retain]; 
    [databaseName retain]; 


}

}

提前致谢

First of all, I know that I should not use an SQLite database to store image, but I only store favicon of website which are really small.

My problem is that I try to insert those favicon into the database (seems to work), I convert the favicon to NSData with the -tiffrepresentation method of NSimage and then insert it to my database into a blob column:

 NSImage *favico = [webview mainFrameIcon];
[appDelegate insertBookmark:[titleField stringValue] url:[urlfield stringValue] data:[favico TIFFRepresentation]]

The SQLite method look like this:

-(void)insertBookmark:(NSString *)title url:(NSString *)url data:(NSData *)data
{
    NSData *imagedata = [[NSData alloc]initWithData:data]; 
    sqlite3 *database;
    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
        NSString *query = [NSString stringWithFormat:@"INSERT INTO Bookmarks (title, url, image) VALUES ('%@', '%@', '%@')",title, url, data];
        const char *querychar = [query UTF8String]; 
        sqlite3_stmt *statement; 
        if (sqlite3_prepare_v2(database, querychar, -1, &statement, NULL) == SQLITE_OK)
        {
            int row =  3;
            sqlite3_bind_blob(statement, row, [imagedata bytes], [imagedata length], NULL);
            sqlite3_step(statement);
            sqlite3_finalize(statement);

        }
        else
        {
            NSLog(@"Error"); 
        }

        [databasePath retain]; 
        [databaseName retain]; 
    }
    sqlite3_close(database);
    [imagedata release]; 

}

When I look into the database I have value in the image column between <data> (normal ? )

Now when I extract the blob from the database and try to put it in my object I got null in the NSimage:

-(void) readDatabase {
// Setup the database object
sqlite3 *database;

bookmarks = [[NSMutableArray alloc] init];

// Open the database from the users filessytem
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
    // Setup the SQL Statement and compile it for faster access
    const char *sqlStatement = "SELECT * FROM Bookmarks ORDER BY title ASC";
    sqlite3_stmt *compiledStatement;
    if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
        // Loop through the results and add them to the feeds array
        while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
            // Read the data from the result row
            NSString *aTitle = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
            NSString *aUrl = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
            NSData *data = [[NSData alloc] initWithBytes:sqlite3_column_blob(compiledStatement, 3) length:sqlite3_column_bytes(compiledStatement, 3)];
            NSImage *image = [[NSImage alloc]initWithData:data];
            bookmarkObject *bookmark = [[bookmarkObject alloc] initWithName:aTitle url:aUrl favico:image]; 

            [bookmarks addObject:bookmark];
            [bookmark release];
            [data release];
            [image release]; 



        }
    }
    // Release the compiled statement from memory
    sqlite3_finalize(compiledStatement);
    sqlite3_close(database); 
    [databasePath retain]; 
    [databaseName retain]; 


}

}

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

↘紸啶 2024-11-11 08:19:02

实际数据周围的 <> 来自 NSData。通过在格式字符串中使用 %@ 并提供 dataNSStringdescription 发送到 data. [NSData description] 将内容包装在 <> 之间。

您的代码的另一个问题是,您似乎混合了无参数和无参数。参数准备语句:

  • 使用 stringWithFormat: 创建完整的查询语句
  • ,或者使用类似 INSERT INTO Bookmarks (title ...) VALUES (? ...) 组合的查询和 sqlite3_bind_blob

SQLite 支持的参数语法可以在这里找到:
http://www.sqlite.org/c3ref/bind_blob.html

The < and > around your actual data come from NSData. By using %@ in your format string and providing data, NSString sends description to data. [NSData description] wraps the content between < and >.

Another issue with your code is, that you seem to mix parameter-less & parameter prepared statements:

  • Either use stringWithFormat: to create a complete query statement
  • or use a query like INSERT INTO Bookmarks (title ...) VALUES (? ...) combined with sqlite3_bind_blob

The parameter syntax SQLite supports can be found here:
http://www.sqlite.org/c3ref/bind_blob.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文