ios 为 iPhone 使用 SQLite 数据库读取和写入图像

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/643682/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 15:44:58  来源:igfitidea点击:

Reading and writing images to an SQLite DB for iPhone use

objective-cioscocoa-touchsqlitensdata

提问by Jeff

I've set up a SQLite DB that currently reads and writes NSStrings perfectly. I also want to store an image in the database and recall it later. I've read up a bit on using NSDataand encoding the image, but I'm not entirely sure what the syntax is for what I want to do. Any code snippets or examples would be greatly appreciated.

我已经建立了一个 SQLite 数据库,它目前可以NSString完美地读写s。我还想在数据库中存储一个图像,稍后再调用。我已经阅读了一些关于使用NSData和编码图像的内容,但我不完全确定我想要做什么的语法是什么。任何代码片段或示例将不胜感激。

My current process goes like this: UIImagePickerController-> User Chooses Image from Photos -> chosenImage is set to instance of UIImageView-> Now I want to take this image and store it in the DB

我当前的过程是这样的: UIImagePickerController-> 用户从照片中选择图像-> selectedImage 设置为实例UIImageView->现在我想拍摄这张图片并将其存储在数据库中

I should mention this call will eventually be replaced with a call to a remote server. Not sure if this makes a difference as far as performance goes.

我应该提到这个调用最终将被对远程服务器的调用所取代。不确定这是否会影响性能。

采纳答案by Lounges

One option (and generally preferred when working in SQL) is to write the image to a file on the system and store the path (or some other kind of identifier) in the database.

一种选择(通常在使用 SQL 时首选)是将图像写入系统上的文件并将路径(或某种其他类型的标识符)存储在数据库中。

回答by Brad Larson

You'll need to convert the UIImage hosted within your UIImageView into a binary BLOB for storage in SQLite. To do that, you can use the following:

您需要将 UIImageView 中托管的 UIImage 转换为二进制 BLOB,以便在 SQLite 中存储。为此,您可以使用以下方法:

NSData *dataForImage = UIImagePNGRepresentation(cachedImage);
sqlite3_bind_blob(yourSavingSQLStatement, 2, [dataForImage bytes], [dataForImage length], SQLITE_TRANSIENT);

This will generate a PNG representation of your image, store it in an NSData instance, and then bind the bytes from the NSData as a BLOB for the second argument in your SQL query. Use UIImageJPEGRepresentation in the above to store in that format, if you like. You will need to have a BLOB column added to the appropriate table in your SQLite database.

这将生成图像的 PNG 表示,将其存储在 NSData 实例中,然后将来自 NSData 的字节绑定为 SQL 查询中第二个参数的 BLOB。如果您愿意,可以使用上面的 UIImageJPEGRepresentation 以该格式存储。您需要将 BLOB 列添加到 SQLite 数据库中的相应表中。

To retrieve this image, you can use the following:

要检索此图像,您可以使用以下命令:

NSData *dataForCachedImage = [[NSData alloc] initWithBytes:sqlite3_column_blob(yourLoadingSQLStatement, 2) length: sqlite3_column_bytes(yourLoadingSQLStatement, 2)];       
self.cachedImage = [UIImage imageWithData:dataForCachedImage];
[dataForCachedImage release];

回答by orj

Apple's recommendation is not to store BLOB's in SQLite databases that are bigger than ~2 kilobytes.

Apple 的建议是不要将 BLOB 存储在大于约 2 KB 的 SQLite 数据库中。

SQLite organizes databases into pages. Each page is 4 kilobytes in size. When you read data from the SQLite database file it loads these pages into an internal page cache. On the iPhone I think this cache defaults to 1 megabyte in size. This makes reading adjacent records very fast because they will probably be in the page cache already.

SQLite 将数据库组织成页面。每页大小为 4 KB。当您从 SQLite 数据库文件读取数据时,它会将这些页面加载到内部页面缓存中。在 iPhone 上,我认为这个缓存的默认大小为 1 兆字节。这使得读取相邻记录非常快,因为它们可能已经在页面缓存中。

When SQLite reads your database record into memory it reads the entire record and all of the pages that it occupies. So if your record contains a BLOB, it could occupy many pages and you will be ejecting existing pages from the cache and replacing them with your BLOB record's pages.

当 SQLite 将您的数据库记录读入内存时,它会读取整个记录及其占用的所有页面。因此,如果您的记录包含 BLOB,它可能会占用许多页面,您将从缓存中弹出现有页面并用 BLOB 记录的页面替换它们。

This isn't so bad if you're just scanning through and loading all your BLOBS to do something with them (display them for example). But if say you did a query where you just wanted to get some data that is in the same row as the BLOB this query would be much slower than if the record did not contain the large BLOB.

如果您只是扫描并加载所有 BLOBS 以对它们执行某些操作(例如显示它们),这还不错。但是,如果假设您执行了一个查询,您只想获取与 BLOB 位于同一行中的一些数据,那么该查询将比记录不包含大 BLOB 的情况慢得多。

So at a minimum you should store your BLOB data in a separate table. Eg:

因此,您至少应该将 BLOB 数据存储在单独的表中。例如:

CREATE TABLE blobs ( id INTEGER PRIMARY KEY, data BLOB );
CREATE TABLE photos ( id INTEGER PRIMARY KEY, name TEXT, blob_id INTEGER, 
    FOREIGN KEY(blob_id) REFERENCES blobs(id) );

Or better yet, store the BLOB data as files outside of the SQLite database.

或者更好的是,将 BLOB 数据存储为 SQLite 数据库之外的文件。

Note that it may be possible to tweak the page cache size with SQL PRAGMA statements(if you're not using CoreData).

请注意,可以使用SQL PRAGMA 语句调整页面缓存大小(如果您不使用 CoreData)。

回答by Xorsat

Writing Image to SQLite DB

将图像写入 SQLite DB

if(myImage != nil){
    NSData *imgData = UIImagePNGRepresentation(myImage);
    sqlite3_bind_blob(update_stmtement, 6, [imgData bytes], [imgData length], NULL);    
    }
    else {
        sqlite3_bind_blob(update_stmtement, 6, nil, -1, NULL);
    }

Reading From SQLite DB:

从 SQLite 数据库读取:

NSData *data = [[NSData alloc] initWithBytes:sqlite3_column_blob(init_statement, 6) length:sqlite3_column_bytes(init_statement, 6)];
        if(data == nil)
            NSLog(@"No image found.");
        else
            self.pictureImage = [UIImage imageWithData:data];   

回答by Kiran Kulkarni

The best practice is to compress the image and store it in the database or file system. If you don't care about the resolution of the image you can go ahead and even resize the image by using :

最佳做法是压缩图像并将其存储在数据库或文件系统中。如果您不关心图像的分辨率,您可以继续使用,甚至可以使用以下方法调整图像大小:

   UIGraphicsBeginImageContext(newSize);  
   [image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];   
   UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();    
   UIGraphicsEndImageContext();

After that you can use UIImageJPEGRepresentationfor jpeg images with a value of "0" for maximum compression. Or you can use UIImagePNGRepresentationfor png images

之后,您可以使用UIImageJPEGRepresentation值为“0”的 jpeg 图像进行最大压缩。或者您可以UIImagePNGRepresentation用于 png 图像

回答by Siddhesh Mahadeshwar

you should first write image on file system. and then take the image path and store that image path(URL) as TEXT in sqlite.

您应该首先在文件系统上写入图像。然后取图像路径并将该图像路径(URL)作为 TEXT 存储在 sqlite 中。