Як зберігати зображення в базі даних 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;



   }

  }
 }

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

будь ласка, зверніться за цим посиланням. Ви точно отримаєте чітке уявлення. stackoverflow.com/questions/11790104/…
весна

Відповіді:


119

Для зберігання зображення потрібно використовувати "крапку".

наприклад: для збереження зображення в 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;
} 

тут ви вставляєте конкретне зображення в базу даних, але мені потрібно вибрати зображення з галереї, а потім мені потрібно вставити це зображення в базу даних і отримати це зображення.
user1083266

4
щоб вибрати зображення з галереї, поставте відповідь на це запитання. stackoverflow.com/questions/2507898/... використовуючи це кодування, ви можете завантажити зображення галереї у растрове зображення. після цього зберігати це растрове зображення в db, як я показую його тут.
Джам

34

Використовуйте BLOB для зберігання вашого зображення у вашій базі даних sqlite. Нижче наведено приклад того, як користуватися крапкою.

Налаштування бази даних

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

}

О ні! Ви роздуєте свою базу даних! Ви кажете, що вважаєте, що це найкраще, чи є у вас причина, чому ви так вважаєте?
Євген Картоєв

4

Для збереження будь-якого зображення в базі даних sqlite вам потрібно зберегти це зображення в байтовому масиві замість рядка. Перетворіть це зображення в байтовий масив і збережіть цей байт [] у БД. Під час отримання цього зображення ви отримаєте байт [], перетворіть цей байт [] у растрове зображення, за допомогою якого ви отримаєте оригінальне зображення.


1

У мене є дві речі, на які я повинен звернути увагу. Як зберігати зображення з галереї та як зберігати зображення з uri, наприклад (www.example.com/myimage.png)

Як зберігати зображення з галереї

Зображення отримуються з галереї, повідомляючи про тип даних Uri. Для того, щоб зберігати зображення в базі даних Android SQLite, вам потрібно перетворити uri зображення в растрове зображення, а потім у двійкові символи, тобто послідовність байтів []. Потім встановіть тип даних стовпця таблиці як тип даних BLOB. Після отримання зображень з БД перетворіть тип даних байт [] у растрове зображення, щоб встановити його на перегляд зображень.

як зберегти зображення з.

Зверніть увагу, що ви можете зберігати зображення в БД як рядок uri, але лише зображення uri з веб-сайту. Перетворіть uri у рядок та вставте його у свою базу даних. Витягніть зображення uri у вигляді рядка та перетворіть на тип даних uri, щоб встановити його на перегляд зображення.

Ви можете спробувати цю публікацію для працюючої програми та вихідного коду, як зберігати зображення у базі даних Sqlite та відображати у списку


Щоб зберегти зображення з галереї, виберіть його, використовуючи дозволи на читання, а потім перетворіть це зображення у растрове зображення, а потім у байтовий масив, щоб зберегти його у базі даних.
Рамандіп Сінгх

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

}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.