programacion - manual de android en pdf
Cómo almacenar imágenes en la base de datos SQLite (5)
Creo que la mejor manera de almacenar una imagen en una base de datos SQLLite es usar el algoritmo Base 64. que convierte una imagen a texto simple y viceversa. Puede descargar el ejemplo completo de Android en: http://developersfound.com/Base64FromStream.zip . Este programa no almacena la imagen pero convierte la imagen de imagen a texto y viceversa.
Aquí está la clase:
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;
}
}
Y aquí está la actividad principal que usa la clase:
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;
}
};
}
En mi aplicación, estoy cargando una imagen desde la galería y quiero almacenar esta imagen en la base de datos SQLite. ¿Cómo almaceno un mapa de bits en la base de datos? Estoy convirtiendo bitmap en una cadena y guardándola en la base de datos. Al recuperarlo de la base de datos, no puedo asignar esa cadena a ImageView ya que es una cadena.
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;
}
}
}
}
}
Para almacenar cualquier imagen en la base de datos sqlite, necesita almacenar esa imagen en una matriz de bytes en lugar de cadena. Convierta esa imagen en matriz de bytes y almacene ese byte [] en DB. Al recuperar esa imagen obtendrá byte [] convertir ese byte [] a mapa de bits por el cual obtendrá la imagen original.
Tengo dos cosas que debo tener en cuenta. Cómo almacenar una imagen de la galería y cómo almacenarla desde uri, p. Ej. (Www.example.com/myimage.png)
Cómo almacenar una imagen desde la galería
Las imágenes se recuperan de la galería informan sobre el tipo de datos de Uri. Para almacenar las imágenes en la base de datos SQLite de Android, debe convertir la uri de la imagen en mapa de bits y luego en caracteres binarios, es decir, secuencia de bytes []. A continuación, establezca el tipo de datos de columna de la tabla como tipo de datos BLOB. Después de recuperar las imágenes de DB, convierta el tipo de datos byte [] a bitmap para establecerlo en la vista de imagen.
cómo almacenar imágenes desde uri.
Tenga en cuenta que puede almacenar imágenes en DB como uri string pero solo image uri desde un sitio web. Convierta el uri a cadena e insértelo en su base de datos. Recupere su imagen uri como cadena y conviértala en uri tipo de datos para configurarla en la vista de imagen.
Puede probar esta publicación para el programa trabajado y el código fuente cómo almacenar imágenes en la base de datos Sqlite y mostrarlas en la lista vista
Use blob para almacenar su imagen en su base de datos sqlite. A continuación se muestra un ejemplo sobre cómo usar blob.
Configurando la base de datos
CREATE TABLE " + DB_TABLE + "("+
KEY_NAME + " TEXT," +
KEY_IMAGE + " BLOB);";
Insertar en la base de datos:
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 );
}
Recuperando datos :
byte[] image = cursor.getBlob(1);
Nota:
- Antes de insertar en la base de datos, primero debe convertir su imagen de mapa de bits en una matriz de bytes y luego aplicarla mediante la consulta de la base de datos.
- Al recuperar de la base de datos, sin duda tiene una matriz de bytes de imagen, lo que necesita hacer es convertir la matriz de bytes de nuevo a la imagen original. Por lo tanto, debe usar BitmapFactory para decodificar.
A continuación hay una clase de utilidad que espero pueda ayudarlo:
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);
}
}
tienes que usar "blob" para almacenar la imagen.
ex: para almacenar una imagen en db
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();
}
para recuperar una imagen de db
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 ;
}