Pergunta

Eu configurei um SQLite DB que atualmente lê e escreve NSStrings perfeitamente. Eu também quero guardar uma imagem no banco de dados e recuperá-lo mais tarde. Eu li um pouco sobre o uso NSData e que codifica a imagem, mas eu não sou inteiramente certo o que a sintaxe é para o que eu quero fazer. Quaisquer fragmentos de código ou exemplos seria muito apreciada.

Meu processo atual é assim: UIImagePickerController -> O utilizador escolhe a imagem de Fotografias -> chosenImage está definido como instância de UIImageView -> Agora eu quero tirar essa imagem e armazená-lo no DB

Eu devo mencionar esta chamada acabará por ser substituída por uma chamada para um servidor remoto. Não sei se isso faz a diferença, tanto quanto o desempenho vai.

Foi útil?

Solução

Uma opção (e geralmente preferido quando se trabalha em SQL) é escrever a imagem para um arquivo no sistema e armazenar o caminho (ou algum outro tipo de identificador) no banco de dados.

Outras dicas

Você vai precisar para converter o UIImage hospedado dentro do seu UIImageView em um BLOB binário para o armazenamento em SQLite. Para fazer isso, você pode usar o seguinte:

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

Isso irá gerar uma representação PNG da sua imagem, armazená-lo em uma instância NSData, e depois ligam os bytes do NSData como um BLOB para o segundo argumento na sua consulta SQL. Use UIImageJPEGRepresentation no exemplo acima à loja nesse formato, se quiser. Você precisará ter uma coluna BLOB adicionada à tabela apropriada em seu banco de dados SQLite.

Para recuperar esta imagem, você pode usar o seguinte:

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

recomendação da Apple não é a loja de BLOB de em bancos de dados SQLite que são maiores do que ~ 2 kilobytes.

SQLite organiza bases de dados em páginas. Cada página é de 4 kilobytes de tamanho. Quando você ler dados a partir do arquivo de banco de dados SQLite ele carrega estas páginas em um cache de página interna. No iPhone Acho que este padrão de cache para 1 megabyte de tamanho. Isto torna a leitura registros adjacentes muito rápido, porque eles provavelmente estarão no cache da página já.

Quando SQLite lê seu registro de banco de dados na memória ele lê o registro inteiro e todas as páginas que ele ocupa. Portanto, se seu registro contém um BLOB, ele poderia ocupar muitas páginas e você será páginas existentes ejetar do cache e substitui-los com as páginas do seu recorde BLOB.

Este não é tão ruim se você está apenas a digitalização através e carregar todas as suas gotas de fazer alguma coisa com eles (exibi-los, por exemplo). Mas se diz que fez uma consulta em que você só queria obter alguns dados que está na mesma linha que o BLOB essa consulta seria muito mais lento do que se o registro não continha o grande BLOB.

Assim, no mínimo você deve armazenar seus dados BLOB em uma tabela separada. Por exemplo:

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

Ou ainda melhor, armazenar os dados BLOB como arquivos fora do banco de dados SQLite.

Note-se que pode ser possível ajustar o tamanho do cache página com declarações SQL PRAGMA (se você não estiver usando CoreData).

imagem Escrevendo para 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);
    }

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

você deve primeiro escrever imagem no sistema de arquivos. e em seguida, tomar o caminho da imagem e armazenar esse caminho da imagem (URL) como texto no sqlite.

A melhor prática é para compactar a imagem e armazená-lo no sistema de banco de dados ou arquivo. Se você não se preocupam com a resolução da imagem que você pode ir em frente e até mesmo redimensionar a imagem usando:

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

Depois que você pode usar UIImageJPEGRepresentation para imagens JPEG com um valor de "0" para a compressão máxima. Ou você pode usar UIImagePNGRepresentation para PNG

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top