2012-02-20 139 views
53

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.Cómo almacenar imágenes en la base de datos SQLite

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; 
    } 
    } 
    } 
} 
} 
+0

consulte este enlace. Definitivamente obtendrás una idea clara. http://stackoverflow.com/questions/11790104/how-to-storebitmap-image-and-retrieve-image-from-sqlite-database-in-android – spr

+0

Evite almacenar imágenes en la base de datos como una cadena. Convierta la imagen de mapa de bits en un tipo de datos binarios (byte []) e insértelo en DB. Consulte este enlacehttp: //whats-online.info/science-and-tutorials/129/how-to-store-images- in-SQLite-database-in-Android-and-display-in-listview/ –

Respuesta

81

tienes que usar "blob" para almacenar la imagen.

por ejemplo: para guardar una imagen en la que 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 ; 
} 
+0

Aquí está insertando una imagen en particular en la base de datos pero necesito elegir una imagen de la galería y luego tengo que insertar esa imagen en la base de datos y recuperarla imagen. – user1083266

+4

para seleccionar una imagen de la galería compruebe esta pregunta. http://stackoverflow.com/questions/2507898/how-to-pick-a-image-from-gallery-sd-card-for-my-app-in-android utilizando esta codificación puede cargar una imagen de galería en mapa de bits . después de esa tienda ese mapa de bits en db como lo muestro aquí. – Jram

3

Para guardar cualquier imagen en la base de datos SQLite necesita almacenar esa imagen en la matriz de bytes en lugar de cadena. Convierta esa imagen en matriz de bytes & 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.

6

Creo que la mejor manera de almacenar una imagen a una base de datos SQLLite es utilizar 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í es 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í es la actividad principal que utiliza 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; 
     } 
    }; 

} 
18

Uso burbuja para guardar la imagen en su base de datos SQLite. A continuación se muestra un ejemplo sobre cómo usar blob.

Configuración de la base de datos

CREATE TABLE " + DB_TABLE + "("+ 
        KEY_NAME + " TEXT," + 
        KEY_IMAGE + " BLOB);"; 

inserción 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); 
} 

Recuperación de datos:

byte[] image = cursor.getBlob(1); 

Nota:

  1. Antes de la inserción en la base de datos, es necesario convertir la imagen de mapa de bits en la matriz de bytes primero y luego aplicarlo mediante consulta a la base.
  2. 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 a la imagen original. Por lo tanto, debe usar BitmapFactory para decodificar.

A continuación se muestra una clase de utilidad que espero que podría ayudarle a:

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); 
    } 
} 
+0

Bueno, pero debe deshacerse de la secuencia en 'getBytes (Mapa de bits bitmap)' –

+0

No olvide llamar a 'stream.close' justo antes' return stream.toByteArray(); 'para evitar fugas. – CopsOnRoad

1

Tengo dos cosas que necesito tener en cuenta. cómo almacenar la imagen de la galería y cómo almacenar la imagen de uri ejemplo (www.example.com/myimage.png)

Cómo almacenar una imagen de la galería

Las imágenes se recuperan de la galería de informar del tipo de datos 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 imágenes 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.

Usted puede intentar este post para el programa funcionado y source code how to store images in Sqlite database and display in listview

Cuestiones relacionadas