2012-02-20 100 views
53

Trong ứng dụng của tôi, tôi đang tải lên một hình ảnh từ thư viện và tôi muốn lưu trữ hình ảnh này trong cơ sở dữ liệu SQLite. Làm thế nào để lưu trữ một bitmap trong cơ sở dữ liệu? Tôi đang chuyển đổi bitmap thành một chuỗi và lưu nó vào cơ sở dữ liệu. Trong khi lấy nó từ cơ sở dữ liệu, tôi không thể gán chuỗi đó cho ImageView vì nó là một chuỗi.Cách lưu hình ảnh trong cơ sở dữ liệu 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

vui lòng tham khảo liên kết này. Chắc chắn bạn sẽ nhận được ý tưởng rõ ràng. http://stackoverflow.com/questions/11790104/how-to-storebitmap-image-and-retrieve-image-from-sqlite-database-in-android – spr

+0

Tránh lưu trữ hình ảnh vào cơ sở dữ liệu dưới dạng chuỗi. Chuyển đổi hình ảnh bitmap thành kiểu dữ liệu nhị phân (byte []) và chèn nó vào DB .. Vui lòng tham khảo liên kết nàyhttp: //whats-online.info/science-and-tutorials/129/how-to-store-images- trong SQLite-database-in-Android-và-display-in-listview/ –

Trả lời

81

bạn phải sử dụng "blob" để lưu trữ hình ảnh.

ví dụ: để lưu trữ một hình ảnh để 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(); 
} 

để lấy một hình ảnh từ 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

ở đây bạn đang chèn một hình ảnh cụ thể vào cơ sở dữ liệu nhưng tôi cần phải chọn một hình ảnh từ thư viện và sau đó tôi cần chèn hình ảnh đó vào cơ sở dữ liệu và truy xuất hình ảnh. – user1083266

+4

để chọn hình ảnh từ thư viện, hãy kiểm tra câu hỏi này. http://stackoverflow.com/questions/2507898/how-to-pick-a-image-from-gallery-sd-card-for-my-app-in-android bằng cách sử dụng mã hóa này, bạn có thể tải hình ảnh thư viện vào bitmap . sau đó lưu trữ bitmap đó vào db như tôi hiển thị nó ở đây. – Jram

3

Để lưu trữ bất kỳ hình ảnh trong cơ sở dữ liệu SQLite bạn cần lưu trữ hình ảnh đó trong mảng byte thay vì chuỗi. Chuyển đổi hình ảnh đó thành mảng byte & lưu trữ byte đó [] thành DB. Trong khi lấy hình ảnh đó, bạn sẽ nhận được byte [] chuyển đổi byte đó [] thành bitmap mà bạn sẽ nhận được hình ảnh gốc.

6

Tôi tin rằng cách tốt nhất để lưu trữ hình ảnh với một cơ sở dữ liệu SQLLite là sử dụng Thuật toán cơ sở 64. chuyển đổi hình ảnh thành văn bản thuần tuý và ngược lại. Bạn có thể tải xuống dự án Android ví dụ đầy đủ tại: http://developersfound.com/Base64FromStream.zip. Chương trình này không lưu trữ hình ảnh nhưng nó chuyển đổi hình ảnh từ hình ảnh sang văn bản và ngược lại.

Đây là lớp:

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

} 

Và đây là hoạt động chính mà sử dụng lớp:

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

Sử dụng blob để lưu trữ hình ảnh của bạn trong cơ sở dữ liệu SQLite của bạn. Dưới đây là một ví dụ về cách sử dụng blob.

Thiết lập cơ sở dữ liệu

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

Insert trong Cơ sở dữ liệu:

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

dữ liệu Lấy:

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

Lưu ý:

  1. Trước khi chèn vào cơ sở dữ liệu, bạn cần phải chuyển đổi hình ảnh Bitmap của bạn vào mảng byte đầu tiên sau đó áp dụng nó sử dụng truy vấn cơ sở dữ liệu.
  2. Khi truy xuất từ ​​cơ sở dữ liệu, bạn chắc chắn có một mảng byte của hình ảnh, những gì bạn cần làm là chuyển đổi mảng byte trở lại hình ảnh gốc. Vì vậy, bạn phải tận dụng BitmapFactory để giải mã.

Dưới đây là một lớp tiện ích mà tôi hy vọng có thể giúp bạn:

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

Tốt, nhưng bạn nên vứt bỏ luồng trong 'getBytes (bitmap bitmap)' –

+0

Đừng quên gọi 'stream.close' ngay trước' return stream.toByteArray(); 'để tránh rò rỉ. – CopsOnRoad

1

Tôi có hai điều tôi cần phải lưu ý. Làm thế nào để lưu trữ hình ảnh từ bộ sưu tập và làm thế nào để lưu trữ hình ảnh từ uri ví dụ (www.example.com/myimage.png)

Làm thế nào để lưu trữ hình ảnh từ gallery

Hình ảnh được lấy từ bộ sưu tập thông báo cho các kiểu dữ liệu Uri . Theo thứ tự để lưu trữ hình ảnh vào cơ sở dữ liệu SQLite android, bạn cần phải chuyển đổi ảnh uri thành bitmap rồi thành ký tự nhị phân, byte []. Sau đó, thiết lập kiểu dữ liệu cột bảng là kiểu dữ liệu BLOB. Sau khi lấy các hình ảnh từ DB, chuyển đổi kiểu dữ liệu byte [] thành bitmap để đặt nó thành imageview.

cách lưu trữ hình ảnh từ uri.

Lưu ý rằng bạn có thể lưu trữ hình ảnh trong DB dưới dạng chuỗi uri nhưng chỉ uri hình ảnh từ một trang web. Chuyển đổi uri thành chuỗi và chèn nó vào cơ sở dữ liệu của bạn. Truy xuất uri hình ảnh của bạn dưới dạng chuỗi và chuyển đổi thành loại dữ liệu uri để đặt nó thành số lần xem hình ảnh.

Bạn có thể thử bài đăng này cho chương trình đã làm việc và source code how to store images in Sqlite database and display in listview

Các vấn đề liên quan