如何在SQLite数据库中存储图像


77

在我的应用程序中,我正在从图库中上传图像,并且希望将此图像存储在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;



   }

  }
 }

图片类:

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

请参考此链接。肯定你会明白的。 stackoverflow.com/questions/11790104/...
SPR

Answers:


119

您必须使用“斑点”来存储图像。

例如:将图像存储到数据库中:

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

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

在这里,您要在数据库中插入特定的图像,但是我需要从图库中选择一个图像,然后需要将该图像插入数据库中并检索该图像。
user1083266 '02

4
要从图库中选择图像,请检查此问题。stackoverflow.com/questions/2507898/… 使用此编码,您可以将图库图像加载到位图中。之后,将位图存储到数据库中,就像我在这里显示的那样。
拉姆(Jram)2012年

34

使用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);

注意:

  1. 在插入数据库之前,需要先将位图图像转换为字节数组,然后使用数据库查询将其应用。
  2. 从数据库检索时,您肯定有一个字节数组的图像,您需要做的是将字节数组转换回原始图像。因此,您必须利用BitmapFactory进行解码。

以下是实用程序类,希望对您有所帮助:

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

1
不错,但是您应该将流getBytes(Bitmap bitmap)
分配

5
别忘了stream.close马上打电话return stream.toByteArray();以免泄漏。
CopsOnRoad

@LazyNinja如何在字节数组中传递选定的图像 stackoverflow.com/questions/63610127/…–
Karthickyuvan

@Karthickyuvan我已经看到你的问题了。除了传递图像外,为什么不传递COLUMN_ID?由于您可以从任何地方访问数据库,因此只需使用columnId检索图像。希望能帮助到你。
懒忍者

我无法插入图片!
Karthickyuvan

6

我相信将图像存储到SQLLite数据库的最佳方法是使用Base 64算法。它将图像转换为纯文本并再次返回。您可以在以下网址下载完整的示例Android项目:www.developersfound.com/Base64FromStream.zip。该程序不存储图像,但会将图像从图像转换为文本,然后再转换回文本。上面的下载链接包含下面的Kotlin代码版本。

这是课程:

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

}

不好了!您将使数据库膨胀!您说您相信最好,您有理由相信吗?
Eugene Kartoyev

4

要将任何图像存储在sqlite数据库中,您需要将该图像存储在字节数组而不是字符串中。将该图像转换为字节数组并将该字节[]存储到DB。检索该图像时,您将获得字节[],将该字节[]转换为可获取原始图像的位图。


1

我有两件事要注意。如何从图库中存储图像以及如何从uri中存储图像,例如(www.example.com/myimage.png)

如何存储图库中的图像

从图库中获取有关Uri数据类型的信息。为了将图像存储到android SQLite数据库,您需要将图像uri转换为位图,然后转换为二进制字符,即bytes []序列。然后将表列数据类型设置为BLOB数据类型。从数据库检索图像后,将byte []数据类型转换为位图,以便将其设置为imageview。

如何从uri存储图像。

请注意,您可以将图像作为uri字符串存储在DB中,但只能将网站中的图像uri存储。将uri转换为字符串并将其插入数据库。以字符串形式检索图像uri并转换为uri数据类型,以便将其设置为imageview。

您可以尝试此帖子以获取有效的程序和源代码,以及如何在Sqlite数据库中存储图像并在listview中显示


要从图库中存储图像,请使用读取权限选择图像,然后将该图像转换为位图图像,然后转换为字节数组以将其存储在数据库中。
Ramandeep Singh,

0

不要忘记在清单文件中写入用户权限代码

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

}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.