读取图像并将其写入 SQLite DB 以供 iPhone 使用

发布于 2024-07-15 05:11:31 字数 387 浏览 7 评论 0原文

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

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

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

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 NSData and 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.

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

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.

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

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

发布评论

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

评论(6

他夏了夏天 2024-07-22 05:11:31

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

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

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

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

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

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:

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.

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];
千紇 2024-07-22 05:11:31

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

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.

燃情 2024-07-22 05:11:31

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

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

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

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

因此,至少您应该将 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) );

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

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

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

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.

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.

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.

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

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.

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

向日葵 2024-07-22 05:11:31

将图像写入 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);
    }

从 SQLite DB 读取:

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];   

Writing Image to 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:

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];   
冬天旳寂寞 2024-07-22 05:11:31

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

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

羁拥 2024-07-22 05:11:31

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

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

之后,您可以将 UIImageJPEGRepresentation 用于 jpeg 图像,值为“0”以实现最大压缩。 或者您可以对 png 图像使用 UIImagePNGRepresentation

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 UIImageJPEGRepresentation for jpeg images with a value of "0" for maximum compression. Or you can use UIImagePNGRepresentation for png images

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