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

问题描述 投票:68回答:5

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



   }

  }
 }

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;
    }
   }
  }
 }
}
android sqlite android-emulator
5个回答
102
投票

你必须使用“blob”来存储图像。

例如:将图像存储到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();
}

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

29
投票

使用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. 在插入数据库之前,需要先将Bitmap图像转换为字节数组,然后使用数据库查询应用它。
  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);
    }
}

7
投票

我相信将图像存储到SQLLite数据库的最佳方法是使用Base 64算法。它将图像转换为纯文本并再次返回。您可以在以下网址下载完整的示例Android项目:http://developersfound.com/Base64FromStream.zip。此程序不存储图像,但它确实将图像从图像转换为文本并再次返回。

这是班级:

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

}

4
投票

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


1
投票

我有两点需要注意。如何存储图库中的图像以及如何存储来自uri的图像,例如(www.example.com/myimage.png)

如何存储图库中的图像

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

如何存储来自uri的图像。

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

你可以尝试这个职位的工作程序和source code how to store images in Sqlite database and display in listview

© www.soinside.com 2019 - 2024. All rights reserved.