web-dev-qa-db-ja.com

iPhone用のSQLiteDBへの画像の読み取りと書き込み

現在NSStringsを完全に読み書きするSQLiteDBをセットアップしました。また、画像をデータベースに保存して、後で呼び出したいと思います。 NSDataの使用と画像のエンコードについて少し読みましたが、自分がやりたいことの構文が何であるか完全にはわかりません。コードスニペットや例をいただければ幸いです。

私の現在のプロセスは次のようになります:UIImagePickerController->ユーザーが写真から画像を選択-> chosenImageはUIImageView->のインスタンスに設定されますこの画像をDBに保存します

この呼び出しは、最終的にはリモートサーバーへの呼び出しに置き換えられることに注意してください。これがパフォーマンスに関する限り違いを生むかどうかはわかりません。

22
Jeff

1つのオプション(およびSQLで作業する場合に一般的に推奨される)は、システム上のファイルにイメージを書き込み、データベースにパス(または他の種類の識別子)を格納することです。

9
Lounges

UIImageView内でホストされているUIImageを、SQLiteに保存するためのバイナリBLOBに変換する必要があります。これを行うには、次を使用できます。

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

これにより、画像のPNG表現が生成され、NSDataインスタンスに格納されてから、NSDataのバイトがSQLクエリの2番目の引数のBLOBとしてバインドされます。必要に応じて、上記のUIImageJPEGRepresentationを使用して、その形式で保存します。 SQLiteデータベースの適切なテーブルにBLOB列を追加する必要があります。

この画像を取得するには、次を使用できます。

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

Appleの推奨事項は、最大2キロバイトを超えるSQLiteデータベースにBLOBを格納しないことです。

SQLiteはデータベースをページに編成します。各ページのサイズは4キロバイトです。 SQLiteデータベースファイルからデータを読み取ると、これらのページが内部ページキャッシュに読み込まれます。 iPhoneでは、このキャッシュのデフォルトのサイズは1メガバイトだと思います。これにより、隣接するレコードはおそらくすでにページキャッシュにあるため、非常に高速に読み取ることができます。

SQLiteがデータベースレコードをメモリに読み込むと、レコード全体とそれが占めるすべてのページが読み込まれます。したがって、レコードにBLOBが含まれている場合、それは多くのページを占める可能性があり、既存のページをキャッシュから取り出して、BLOBレコードのページに置き換えることになります。

すべてのBLOBをスキャンしてロードし、それらを使用して何かを実行する場合(たとえば、それらを表示する場合)、これはそれほど悪くありません。ただし、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を使用していない場合)を使用してページキャッシュサイズを微調整できる場合があることに注意してください。

9
orj

SQLiteDBへのイメージの書き込み

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

ベストプラクティスは、イメージを圧縮してデータベースまたはファイルシステムに保存することです。画像の解像度を気にしない場合は、次を使用して画像のサイズを変更することもできます。

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

その後、最大圧縮率の値が「0」のjpeg画像にはUIImageJPEGRepresentationを使用できます。または、png画像にUIImagePNGRepresentationを使用できます

0
Kiran Kulkarni

最初にファイルシステムにイメージを書き込む必要があります。次に、画像パスを取得し、その画像パス(URL)をテキストとしてsqliteに保存します。