DJhon
DJhon

Reputation: 1518

Save image in SQLite database from server URL

Hi every body i am stuck with a problem that how to save images in our SQLite database . Image reside at particular url e.g.- http://images.201bestbuy.com/images/small_137385013870957.jpg

Now i want to save image in my sqlit database from this url without user interaction. To solve this issue i used

public class ImageLoader {

    MemoryCache memoryCache = new MemoryCache();
    FileCache fileCache;
    private Map<ImageView, String> imageViews = Collections
        .synchronizedMap(new WeakHashMap<ImageView, String>());
    ExecutorService executorService;

    public ImageLoader(Context context) {
        fileCache = new FileCache(context);
        executorService = Executors.newFixedThreadPool(5);
    }

    final int stub_id = R.drawable.no_image;

    public void DisplayImage(String url, ImageView imageView) {
        imageViews.put(imageView, url);
        Bitmap bitmap = memoryCache.get(url);
        if (bitmap != null){
            imageView.setImageBitmap(bitmap);
        }
        else {
            queuePhoto(url, imageView);
            imageView.setImageResource(stub_id);
        }
    }

    private void queuePhoto(String url, ImageView imageView) {
        PhotoToLoad p = new PhotoToLoad(url, imageView);
        executorService.submit(new PhotosLoader(p));
    }

    private Bitmap getBitmap(String url) {
        File f = fileCache.getFile(url);

        // from SD cache
        Bitmap b = decodeFile(f);
        if (b != null)
            return b;

        // from web
        try {
            Bitmap bitmap = null;
            URL imageUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) imageUrl
                .openConnection();
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            conn.setInstanceFollowRedirects(true);
            InputStream is = conn.getInputStream();
            OutputStream os = new FileOutputStream(f);
            Utils.CopyStream(is, os);
            os.close();
            bitmap = decodeFile(f);

            return bitmap;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    // decodes image and scales it to reduce memory consumption
    private Bitmap decodeFile(File f) {
        try {
            // decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(f), null, o);
            // Find the correct scale value. It should be the power of 2.
            final int REQUIRED_SIZE = 70;
            int width_tmp = o.outWidth, height_tmp = o.outHeight;
            int scale = 1;
            while (true) {
                if (width_tmp / 2 < REQUIRED_SIZE
                    || height_tmp / 2 < REQUIRED_SIZE)
                    break;
                width_tmp /= 2;
                height_tmp /= 2;
                scale *= 2;
            }

            // decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (FileNotFoundException e) {
    }
    return null;
}

// Task for the queue
private class PhotoToLoad {
    public String url;
    public ImageView imageView;

    public PhotoToLoad(String u, ImageView i) {
        url = u;
        imageView = i;
    }
}

class PhotosLoader implements Runnable {
    PhotoToLoad photoToLoad;

    PhotosLoader(PhotoToLoad photoToLoad) {
        this.photoToLoad = photoToLoad;
    }

    @Override
    public void run() {
        if (imageViewReused(photoToLoad))
            return;
        Bitmap bmp = getBitmap(photoToLoad.url);
        memoryCache.put(photoToLoad.url, bmp);
        if (imageViewReused(photoToLoad))
            return;
        BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad);
        Activity a = (Activity) photoToLoad.imageView.getContext();
        a.runOnUiThread(bd);
    }
}

boolean imageViewReused(PhotoToLoad photoToLoad) {
    String tag = imageViews.get(photoToLoad.imageView);
    if (tag == null || !tag.equals(photoToLoad.url))
        return true;
    return false;
}

// Used to display bitmap in the UI thread
class BitmapDisplayer implements Runnable {
    Bitmap bitmap;
    PhotoToLoad photoToLoad;

    public BitmapDisplayer(Bitmap b, PhotoToLoad p) {
        bitmap = b;
        photoToLoad = p;
    }

    public void run() {
        if (imageViewReused(photoToLoad))
            return;
        if (bitmap != null){
            photoToLoad.imageView.setImageBitmap(bitmap);

        }
        else
            photoToLoad.imageView.setImageResource(stub_id);
    }
}

public void clearCache() {
    memoryCache.clear();
    fileCache.clear();
}

}

Now Problem is that when i am using

    ContentValues userdetailValues = new ContentValues();
    userdetailValues.put("Key_ProductImage",imageView.setImageBitmap(bitmap)); 

When i am using these code for saving images in SQLite database. It shows a error for me. Put() method takes both parameter as string but return type of setImageBitmap(bitmap) is void. If my approach is totally wrong then please suggest me right way to resolve this issue.

Upvotes: 0

Views: 4435

Answers (2)

Sai Kiran
Sai Kiran

Reputation: 465

I feel this is a bad way of storing the images but providing the answer to store an image to database.

You can convert the image bitmap to bytes using below code

public static byte[] getBytes(Bitmap bitmap)
{
    ByteArrayOutputStream stream=new ByteArrayOutputStream();
    bitmap.compress(CompressFormat.JPEG,0, stream);
   return stream.toByteArray();
}

and you can insert to database as blob data as follows:

ContentValues cv=new ContentValues();
cv.put(data, image);
return db.insert(TABLE_NAME, null, cv);

Here the image data to be of type BLOB while inserting.

Upvotes: 2

Gabe Sechan
Gabe Sechan

Reputation: 93569

Putting the image in the db is a bad way of doing things- you bloat the db and get data out of it that then needs to be converted to the right format. Instead, store it to disk and put the filename you stored it to in the db. Then load it from disk.

Upvotes: 1

Related Questions