0

The photos don't appear into my app. My code for load it is the following:

private static final String TAG = "ERROR";
private static final int IO_BUFFER_SIZE = 4 * 1024;
public static Bitmap loadBitmap(String url) {
    Bitmap bitmap = null;
    InputStream in = null;
    BufferedOutputStream out = null;

    try {
        Log.e(TAG, "OK0");

        in = new BufferedInputStream(new URL(url).openStream(), IO_BUFFER_SIZE);
        Log.e(TAG, "OK1");

        final ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
        out = new BufferedOutputStream(dataStream, IO_BUFFER_SIZE);
        copy(in, out);
        out.flush();

        final byte[] data = dataStream.toByteArray();
        BitmapFactory.Options options = new BitmapFactory.Options();
        //options.inSampleSize = 1;

        bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,options);
    } catch (IOException e) {
        Log.e(TAG, "Could not load Bitmap from: " + url);
    } finally {
        closeStream(in);
        closeStream(out);
    }

    return bitmap;
}

the problem is in first line of try:

in = new BufferedInputStream(new URL(url).openStream(), IO_BUFFER_SIZE);

and the php file:

    $objQuery = mysql_query("SELECT * FROM Photos WHERE 1");

    $intNumField = mysql_num_fields($objQuery);
    $resultArray = array();
    while($obResult = mysql_fetch_array($objQuery))
    {
            $arrCol = array();
            for($i=0;$i<$intNumField;$i++)
            {
                    $arrCol[mysql_field_name($objQuery,$i)] = $obResult[$i];
            }
            array_push($resultArray,$arrCol);
    }

    mysql_close($con);

    echo json_encode($resultArray);

The output in Android is the correct url, but don't display into Imageview:

E/ERRORīš• Could not load Bitmap from:xxxxx

I've got the code from other page, because I've tried some examples and never works. Only when I put the url into Android, but when I can get more than one from Mysql never show me the photo only the correct url, so the problem I think is when I try convert the url to bitmap.

Thanks for the answer.

CapAm
  • 217
  • 3
  • 18

2 Answers2

0

you just convert byte array from data base to bitmap....

Dinesh Bagvan
  • 129
  • 1
  • 3
0

im assuming you are using a link location in the mysql and not loading an image that is stored in the database(because that is very inefficient) if you are using the link route is the best way to load those images. Note that this can be used for loading multiple images at once without slowing down your app. Like loading a bunch of profile pictures on a newsfeed.

I have a dating app out that loads multiple profile pictures and posted images to the same activity. In order to do this the best way(and pretty much the only way) is to cache the images. Here is some detailed code with comments to help you do this. Make sure to read the comments because they will help you if you need to edit my code for optimizing your app.

First you need to copy this code to your app as a separate class

ImageLoader.java---you dont need to make any changes to this unless you really need to.

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.Collections;
    import java.util.Map;
    import java.util.WeakHashMap;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import android.app.Activity;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.widget.ImageView;


public class ImageLoader {

    Context context;

    MemoryCache memoryCache=new MemoryCache();//this is another java file you will have to create
    FileCache fileCache;
    private Map<ImageView, String> imageViews=Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
    ExecutorService executorService; 

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


   // final int stub_id = com.swiftkaytech.simdate.R.drawable.ic_launcher;//set this equal to a drawable resource if you want a placeholder for while your images are loading.
    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);//uncomment if you are using a placeholder for while your images are loading.
        }
    }


    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 (Throwable ex){
           ex.printStackTrace();
           if(ex instanceof OutOfMemoryError)
               memoryCache.clear();
           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=160;//this value is how large the file will be. making this bigger might cause issues with memory while making it smaller will reduce image quality
            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() {
            //memoryCache.clear();


            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/*Bitmap.createScaledBitmap(bitmap, newwidth, newheight, true)*/);
            }
           // else
               // photoToLoad.imageView.setImageResource(stub_id);
        }
    }

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



}

FileCache.java again you dont need to make any changes to this unless you really need to

import java.io.File;


import android.content.Context;

public class FileCache {

    private File cacheDir;

    public FileCache(Context context){
        //Find the dir to save cached images
        if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
            cacheDir=context.getCacheDir();//new File(android.os.Environment.getExternalStorageDirectory(),"TTImages_cache");
        else
            cacheDir=context.getCacheDir();
        if(!cacheDir.exists())
            cacheDir.mkdirs();
    }

    public File getFile(String url){
        //I identify images by hashcode. Not a perfect solution, good for the demo.
       String filename=String.valueOf(url.hashCode());
        //Another possible solution (thanks to grantland)
       // String filename = URLEncoder.encode(url);
        File f = new File(cacheDir, filename);
        return f;

    }

    public void clear(){
        File[] files=cacheDir.listFiles();
        if(files==null)
            return;
        for(File f:files)
            f.delete();
    }

}

MemoryCache.java ---no changes needed

import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import android.graphics.Bitmap;
import android.util.Log;

public class MemoryCache {

    private static final String TAG = "MemoryCache";
    private Map<String, Bitmap> cache=Collections.synchronizedMap(
            new LinkedHashMap<String, Bitmap>(10,1.5f,true));//Last argument true for LRU ordering
    private long size=0;//current allocated size
    private long limit=100000;//max memory in bytes

    public MemoryCache(){
        //use 25% of available heap size
        setLimit(Runtime.getRuntime().maxMemory()/6);
    }

    public void setLimit(long new_limit){
        limit=new_limit;
        Log.i(TAG, "MemoryCache will use up to "+limit/1024./1024.+"MB");
    }

    public Bitmap get(String id){
        try{
            if(!cache.containsKey(id))
                return null;
            //NullPointerException sometimes happen here http://code.google.com/p/osmdroid/issues/detail?id=78 
            return cache.get(id);
        }catch(NullPointerException ex){
            ex.printStackTrace();
            return null;
        }
    }

    public void put(String id, Bitmap bitmap){
        try{
            if(cache.containsKey(id))
                size-=getSizeInBytes(cache.get(id));
            cache.put(id, bitmap);
            size+=getSizeInBytes(bitmap);



            checkSize();
        }catch(Throwable th){
            th.printStackTrace();
        }
    }

    private void checkSize() {
        Log.i(TAG, "cache size="+size+" length="+cache.size());
        if(size>limit){
            Iterator<Entry<String, Bitmap>> iter=cache.entrySet().iterator();//least recently accessed item will be the first one iterated  
            while(iter.hasNext()){
                Entry<String, Bitmap> entry=iter.next();
                size-=getSizeInBytes(entry.getValue());
                iter.remove();
                if(size<=limit)
                    break;
            }
            Log.i(TAG, "Clean cache. New size "+cache.size());
        }
    }

    public void clear() {
        try{
            //NullPointerException sometimes happen here http://code.google.com/p/osmdroid/issues/detail?id=78 
            cache.clear();
            size=0;
        }catch(NullPointerException ex){
            ex.printStackTrace();
        }
    }

    long getSizeInBytes(Bitmap bitmap) {
        if(bitmap==null)
            return 0;
        return bitmap.getRowBytes() * bitmap.getHeight();
    }
}

Now on the activity(or in an adapter if using a listview/gridview or such put this code

ImageLoader imageLoader;

imageLoader = new ImageLoader(context);//change this as needed to be your activities context

imageLoader.DisplayImage(url, imageview);//the url is the link to the photo and imageview is the imageview you are going to display the image.