2012-02-20 8 views
53

W mojej aplikacji ładuję obraz z galerii i chcę go zapisać w bazie danych SQLite. Jak zapisać bitmapę w bazie danych? Konwertuję bitmapę na ciąg znaków i zapisuję go w bazie danych. Podczas pobierania go z bazy danych, nie mogę przypisać tego ciągu do ImageView, ponieważ jest to ciąg znaków.Jak przechowywać obraz w bazie danych 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

patrz link. Zdecydowanie dostaniesz jasny pomysł. http://stackoverflow.com/questions/11790104/how-to-storebitmap-image-and-retrieve-image-from-sqlite-database-in-android – spr

+0

Unikaj przechowywania obrazów w bazie danych jako ciąg. Konwertuj obraz bitmapowy na binarny typ danych (bajt []) i wstaw go do bazy danych. Proszę odnieść się do tego linkuhttp: //whats-online.info/science-and-tutorials/129/how-to-store-images- w bazie danych SQLite-in-Android-and-display-in-listview/ –

Odpowiedz

81

musisz użyć "blob" do przechowywania obrazu.

ex: do przechowywania obrazu w celu 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(); 
} 

aby pobrać obraz z 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

tutaj wstawiasz konkretny obraz do bazy danych, ale muszę wybrać obraz z galerii, a następnie muszę wstawić ten obraz do bazy danych i pobrać to obraz. – user1083266

+4

, aby wybrać obraz z galerii, sprawdź to pytanie. http://stackoverflow.com/questions/2507898/how-to-pick-a-image-from-gallery-sd-card-for-my-app-in-android przy użyciu tego kodowania można załadować obraz galerii do bitmapy . po tym przechowywać tę mapę bitową w db jak i to pokazać tutaj. – Jram

3

Aby zapisać dowolny obraz w bazie danych sqlite trzeba zapisać, że obraz w tablicy bajtów zamiast łańcucha. Konwertuj ten obraz na tablicę bajtową & zapisz ten bajt [] do DB. Podczas pobierania tego obrazu otrzymasz bajt [] zamień bajt [] na bitmapę, dzięki której otrzymasz oryginalny obraz.

6

Uważam, że najlepszym sposobem przechowywania obrazu do bazy danych SQLLite jest użycie Algorytm Base 64. który konwertuje obraz na zwykły tekst iz powrotem. Pełny przykładowy projekt Androida można pobrać pod adresem: http://developersfound.com/Base64FromStream.zip. Ten program nie przechowuje obrazu, ale przekształca obraz z obrazu na tekst iz powrotem.

Oto klasa:

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

} 

I tu jest głównym programem, który używa klasy:

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

Zastosowanie kropelka aby zapisać obraz w bazie danych SQLite. Poniżej znajduje się przykład użycia kropli.

konfigurowania bazy danych

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

Insert w bazie danych:

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

pobierania danych:

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

Uwaga:

  1. Przed włożeniem do bazy danych, trzeba konwertować bitmapy do tablicy bajtów pierwszy następnie zastosować je przy użyciu zapytania do bazy danych.
  2. Podczas pobierania z bazy danych, z pewnością masz tablicę bajtów obrazu, co musisz zrobić, aby przekonwertować tablicę bajtów z powrotem na oryginalny obraz. Tak więc musisz użyć BitmapFactory do dekodowania.

Poniżej przedstawiono klasy narzędzie, które mam nadzieję, że mógłby pomóc:

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

Dobrze, ale powinieneś wyrzucić strumień w 'getBytes (Bitmap bitmap)' –

+0

Nie zapomnij wywołać 'stream.close' tuż przed' return stream.toByteArray(); 'aby uniknąć przecieków. – CopsOnRoad

1

Mam dwie rzeczy muszę pamiętać. Jak zapisać obraz z galerii i jak przechowywać obraz z URI np (www.example.com/myimage.png)

Jak zapisać obraz z galerii

Obrazy są pobierane z galerii poinformować Uri typu danych . W celu przechowywania obrazów w bazie danych Android SQLite, musisz przekonwertować uri na mapę bitową, a następnie na znaki binarne, czyli sekwencję bajtów []. Następnie ustaw typ danych kolumny tabeli jako typ danych BLOB. Po pobraniu obrazów z bazy danych, skonwertuj typ danych bajtowych [] na bitmapę, aby ustawić go na podgląd obrazu.

sposób przechowywania obrazu z URI.

Należy pamiętać, że można przechowywać obrazy w DB jako ciąg URI, ale tylko obraz URI ze strony internetowej. Konwertuj uri na ciąg znaków i wstaw go do swojej bazy danych. Odzyskaj uri obraz jako ciąg i przekonwertuj na typ danych uri, aby ustawić go na widok obrazu.

Można spróbować tego posta pracował dla programu i source code how to store images in Sqlite database and display in listview