Как сохранить изображение в базе данных SQLite
В моем приложении я загружаю изображение из галереи и хочу сохранить это изображение в базе данных SQLite. Как сохранить растровое изображение в базе данных? Я преобразовываю растровое изображение в строку и сохраняю ее в базе данных. При извлечении из базы данных я не могу назначить эту строку для ImageView, так как это строка.
Imageupload12.java:
public class Imageupload12 extends Activity {
Button buttonLoadImage;
ImageView targetImage;
int i = 0;
Database database = new Database(this);
String i1;
String img;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main5);
buttonLoadImage = (Button) findViewById(R.id.loadimage);
targetImage = (ImageView) findViewById(R.id.targetimage);
Bundle b = getIntent().getExtras();
if (b != null) {
img = b.getString("image");
targetImage2.setImageURI("image");
//i am getting error as i cant assign string to imageview.
}
buttonLoadImage.setOnClickListener(new Button.OnClickListener() {
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
Log.i("photo", "" + intent);
startActivityForResult(intent, i);
i = i + 1;
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case 0:
if (resultCode == RESULT_OK) {
Uri targetUri = data.getData();
// textTargetUri.setText(targetUri.toString());
Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(targetUri));
targetImage.setImageBitmap(bitmap);
i1 = bitmap.toString();
Log.i("firstimage........", "" + i1);
targetImage.setVisibility(0);
SQLiteDatabase db = database.getWritableDatabase();
db.execSQL("INSERT INTO UPLOAD VALUES('" + i1 + "');");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
break;
}
}
}
Image.class:
public class Image extends Activity {
Database database = new Database(this);
static EfficientAdapter adapter, adapter1;
static ListView lv1;
static SQLiteDatabase db;
static EfficientAdapter adp;
static Cursor c1;
static Vector < String > IMAGE = new Vector < String > ();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
db = database.getReadableDatabase();
c1 = db.rawQuery("select * from UPLOAD;", null);
if (c1.moveToFirst()) {
do {
IMAGE.add(c1.getString(0).toString());
} while (c1.moveToNext());
c1.close();
}
lv1 = (ListView) findViewById(R.id.List);
adapter = new EfficientAdapter(this);
lv1.setAdapter(adapter);
ImageView add = (ImageView) findViewById(R.id.imv1a);
add.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
IMAGE.clear();
Intent i = new Intent(Image.this, Imageupload12.class);
startActivity(i);
}
});
}
private static class EfficientAdapter extends BaseAdapter {
// protected final Context Context = null;
protected LayoutInflater mLayoutInflater;
AlertDialog.Builder aBuilder;
public EfficientAdapter(Context context) {
// TODO Auto-generated constructor stub
mLayoutInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return IMAGE.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
final ViewHolder mVHolder;
if (convertView == null) {
convertView = mLayoutInflater.inflate(R.layout.pjtlistdetails, parent, false);
mVHolder = new ViewHolder();
mVHolder.t1 = (TextView) convertView.findViewById(R.id.pjtdetails);
mVHolder.time = (TextView) convertView.findViewById(R.id.name);
mVHolder.imv = (ImageButton) convertView.findViewById(R.id.editic);
mVHolder.imvd = (ImageView) convertView.findViewById(R.id.delete);
mVHolder.imvf = (ImageView) convertView.findViewById(R.id.fwd);
mVHolder.imv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String img = IMAGE.elementAt(position);
Log.i("image...", "" + img);
Context ctx = v.getContext();
Intent myIntent = new Intent();
ctx = v.getContext();
myIntent.setClass(ctx, Imageupload12.class);
myIntent.putExtra("image", img);
ctx.startActivity(myIntent);
IMAGE.clear();
}
});
static class ViewHolder {
ImageButton imv;
ImageView imvd, imvf;
}
}
}
}
}
5 ответов
Вы должны использовать "blob" для хранения изображения.
например: сохранить изображение в дБ
public void insertImg(int id , Bitmap img ) {
byte[] data = getBitmapAsByteArray(img); // this is a function
insertStatement_logo.bindLong(1, id);
insertStatement_logo.bindBlob(2, data);
insertStatement_logo.executeInsert();
insertStatement_logo.clearBindings() ;
}
public static byte[] getBitmapAsByteArray(Bitmap bitmap) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 0, outputStream);
return outputStream.toByteArray();
}
получить изображение из БД
public Bitmap getImage(int i){
String qu = "select img from table where feedid=" + i ;
Cursor cur = db.rawQuery(qu, null);
if (cur.moveToFirst()){
byte[] imgByte = cur.getBlob(0);
cur.close();
return BitmapFactory.decodeByteArray(imgByte, 0, imgByte.length);
}
if (cur != null && !cur.isClosed()) {
cur.close();
}
return null ;
}
Используйте blob для хранения вашего изображения в вашей базе данных sqlite. Ниже приведен пример использования BLOB-объектов.
Настройка базы данных
CREATE TABLE " + DB_TABLE + "("+
KEY_NAME + " TEXT," +
KEY_IMAGE + " BLOB);";
Вставьте в базу данных:
public void addEntry( String name, byte[] image) throws SQLiteException{
ContentValues cv = new ContentValues();
cv.put(KEY_NAME, name);
cv.put(KEY_IMAGE, image);
database.insert( DB_TABLE, null, cv );
}
Получение данных:
byte[] image = cursor.getBlob(1);
Замечания:
- Перед вставкой в базу данных вам необходимо сначала преобразовать ваше растровое изображение в байтовый массив, а затем применить его с помощью запроса к базе данных.
- При извлечении из базы данных у вас, конечно, есть байтовый массив изображений, и вам нужно преобразовать байтовый массив обратно в исходное изображение. Таким образом, вы должны использовать BitmapFactory для декодирования.
Ниже приведен класс Utility, который, я надеюсь, может вам помочь:
public class DbBitmapUtility {
// convert from bitmap to byte array
public static byte[] getBytes(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.PNG, 0, stream);
return stream.toByteArray();
}
// convert from byte array to bitmap
public static Bitmap getImage(byte[] image) {
return BitmapFactory.decodeByteArray(image, 0, image.length);
}
}
Я считаю, что лучший способ сохранить изображение в базе данных SQLLite - это использовать алгоритм Base 64. который преобразует изображение в простой текст и обратно. Вы можете скачать полный пример проекта Android по адресу: http://developersfound.com/Base64FromStream.zip. Эта программа не сохраняет изображение, но конвертирует изображение из текста в текст и обратно.
Вот класс:
package com.example.TestProject;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;
import android.util.Log;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.FileChannel;
public class Base64CODEC {
private int IO_BUFFER_SIZE = 64;
//private int IO_BUFFER_SIZE = 8192;
private URL urlObject = null;
private URLConnection myConn = null;
ByteArrayOutputStream os = null;
public void Base64CODEC() {}
public Bitmap Base64ImageFromURL(String url) {
Bitmap bitmap = null;
InputStream in = null;
BufferedOutputStream out = null;
try {
urlObject = new URL(url);
myConn = urlObject.openConnection();
in = myConn.getInputStream();
final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
copyCompletely(in, out);
final byte[] data = dataStream.toByteArray();
BitmapFactory.Options options = new BitmapFactory.Options();
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
} catch (IOException e) {
Log.e("TAG", "Could not load Bitmap from: " + url);
} finally {
//closeStream(in);
try {
in.close();
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
//closeStream(out);
try {
out.close();
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
return bitmap;
}
private void copyCompletely(InputStream input, OutputStream output) throws IOException {
// if both are file streams, use channel IO
if ((output instanceof FileOutputStream) && (input instanceof FileInputStream)) {
try {
FileChannel target = ((FileOutputStream) output).getChannel();
FileChannel source = ((FileInputStream) input).getChannel();
source.transferTo(0, Integer.MAX_VALUE, target);
source.close();
target.close();
return;
} catch (Exception e) { /* failover to byte stream version */
}
}
byte[] buf = new byte[8192];
while (true) {
int length = input.read(buf);
if (length < 0)
break;
output.write(buf, 0, length);
}
try {
input.close();
} catch (IOException ignore) {
}
try {
output.close();
} catch (IOException ignore) {}
}
public String convertToBase64(Bitmap bitmap) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG,100,os);
byte[] byteArray = os.toByteArray();
return Base64.encodeToString(byteArray, 0);
}
public Bitmap convertToBitmap(String base64String) {
byte[] decodedString = Base64.decode(base64String, Base64.DEFAULT);
Bitmap bitmapResult = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
return bitmapResult;
}
}
А вот основной вид деятельности, который использует класс:
package com.example.TestProject;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.ImageView;
public class MainActivity extends Activity implements Runnable {
private Thread thread = null;
private Bitmap bitmap = null;
private Base64CODEC base64CODEC = null;
private ImageView imgViewSource = null;
private ImageView imgViewDestination = null;
private boolean isSourceImageVisible = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void CmdLoadImage_Click(View view) {
try {
if(isSourceImageVisible == true) {
imgViewSource.setImageBitmap(null);
imgViewDestination.setImageBitmap(null);
isSourceImageVisible = false;
}
else {
base64CODEC = new Base64CODEC();
thread = new Thread(this);
thread.start();
}
}
catch (NullPointerException e) {}
}
public void CmdEncodeImage_Click(View view) {
Base64CODEC base64CODEC = new Base64CODEC();
try {
String base64String = base64CODEC.convertToBase64(bitmap);
imgViewDestination = (ImageView) findViewById(R.id.imgViewDestination);
Bitmap imgViewDestinationBitmap = base64CODEC.convertToBitmap(base64String);
imgViewDestination.setImageBitmap(imgViewDestinationBitmap);
}
catch (NullPointerException e) {
//
}
}
@Override
public void run() {
bitmap = base64CODEC.Base64ImageFromURL("http://developersfound.com/me.png");
handler.sendEmptyMessage(0);
}
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
imgViewSource = (ImageView) findViewById(R.id.imgViewSource);
imgViewSource.setImageBitmap(bitmap);
isSourceImageVisible = true;
thread = null;
}
};
}
Чтобы сохранить любое изображение в базе данных sqlite, вам нужно сохранить это изображение в байтовом массиве вместо строки. Преобразуйте это изображение в байтовый массив и сохраните этот байт [] в БД. При получении этого изображения вы получите byte [], который преобразует этот байт [] в растровое изображение, по которому вы получите исходное изображение.
У меня есть две вещи, которые я должен отметить. Как сохранить изображение из галереи и как сохранить изображение из URI, например (www.example.com/myimage.png)
Как сохранить изображение из галереи
Изображения извлекаются из галереи, информируют о типе данных Uri. Чтобы хранить изображения в базе данных SQLite для Android, необходимо преобразовать изображение URI в растровое изображение, а затем в двоичные символы, то есть последовательность байтов []. Затем установите тип данных столбца таблицы как тип данных BLOB. После извлечения изображений из БД преобразуйте тип данных byte[] в растровое изображение, чтобы установить для него изображение.
Как сохранить изображение из URI.
Обратите внимание, что вы можете хранить изображения в БД в виде строки URI, но только изображения URI с веб-сайта. Преобразуйте URI в строку и вставьте его в свою базу данных. Получите ваше изображение URI в виде строки и преобразовать в тип данных URI, чтобы установить его для изображения.
Вы можете попробовать этот пост для работающей программы и исходного кода, как хранить изображения в базе данных Sqlite и отображать в виде списка.
Не забудьте записать код доступа пользователя в файл манифеста
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CameraActivity = this;
imageView = (ImageView) findViewById(R.id.image_view);
database = new ImageDatabase(this);
//Set OnClick Listener to button view
captureImage = (Button) findViewById(R.id.capture_image);
captureImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
});
}
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
theImage = (Bitmap) data.getExtras().get("data");
ByteArrayOutputStream stream = new ByteArrayOutputStream();
theImage.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
SQLiteDatabase db = database.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(ImageDatabase.KEY_IMG_URL, byteArray);
db.insert(ImageDatabase.TABLE_NAME, null, values);
db.close();
Bitmap b = getTheImage();
imageView.setImageBitmap(b);
}
}
public Bitmap getTheImage(){
SQLiteDatabase db = database.getReadableDatabase();
Cursor cursor = (Cursor) db.rawQuery(" SELECT * FROM "+ImageDatabase.TABLE_NAME,null,null);
if (cursor.moveToFirst()){
byte[] imgByte = cursor.getBlob(cursor.getColumnIndex(ImageDatabase.KEY_IMG_URL));
cursor.close();
return BitmapFactory.decodeByteArray(imgByte,0,imgByte.length);
}
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
return null;
}
}
КЛАСС БАЗЫ ДАННЫХ
class ImageDatabase extends SQLiteOpenHelper {
public Context context;
public static final String DATABASE_NAME = "dataManager";
public static final int DATABASE_VERSION = 1;
public static final String TABLE_NAME = "data";
public static final String KEY_ID = "id";
public static final String KEY_IMG_URL = "ImgFavourite";
public ImageDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.context = context;
//Toast.makeText(context, "Constructor called", Toast.LENGTH_LONG).show();
}
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + "(" + KEY_ID +
" INTEGER PRIMARY KEY AUTOINCREMENT," + KEY_IMG_URL + " BLOB " + ")";
public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLE_NAME + "";
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(DROP_TABLE);
onCreate(db);
}
public void deleteEntry(long row) {
SQLiteDatabase sqLiteDatabase = getWritableDatabase();
sqLiteDatabase.delete(TABLE_NAME, KEY_ID + "=" + row, null);
}
}