2013-10-01 2 views
0

나는 15 개 이상의 비트 맵을 포함하는 ArrayList가 있습니다. 이 비트 맵은 sdcard에서 읽어야합니다. 내 배열은 루프에있다. 그래서 내가 기억에서 비트 맵을 매번 읽고 싶지 않아 캐시 로이 비트 맵을 저장하고 싶습니다. 내 비트 맵의 ​​arraylist는 2Mb보다 작습니다. 캔버스를 사용자 정의보기에 표시하고 싶습니다. 비트 맵 개수 때문에 캐시 또는 다른 것으로 저장하는 것이 좋습니다. 나는 그들이 아주 가벼운 (약 15kb) pleas가 이것을하는 방법을 도울지라도 sdcard에서 15 비트 맵 이상을 읽는 것이 의미가 없다고 생각한다. 각 비트 맵에서 추가로 은 256 * 256 픽셀입니다.캐시 안드로이드에서 비트 맵 배열 목록

Bitmap bmp; 
String zoom = String.valueOf(ZoomLevel); 
File file = new File(Environment.getExternalStorageDirectory()+"/GreatMap/"+zoom); 
File image = FolderExist(ZoomLevel); 
if (file.exists()) 
{ 
    if(image.exists()) 
    { 
     for(int a = 1; a < 20 ;a++) 
     { 
      bmp = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+"/GreatMap/"+zoom+"/"+a+".jpg"); 
      Images.add(a,bmp);       

     } 
     postInvalidate(); 

     } 
} 
+0

및 귀하의 질문은 무엇입니까? (또한, 분명히 19 이미지가 아닌 15 이미지). – njzk2

+0

또한 8888 (32 비트)의 256x256은 250Kb이므로 배열이 ~ 4MB가됩니다. – njzk2

+0

은 JPEG로 압축되어 10-15Kb가됩니다. [link] http://khm0.google.com/kh/v=132&hl=EN&x=0&y=0&z=0&s= 그리고 "more"를 15보다 썼습니다. –

답변

0

다음 클래스를 사용하여 sd 카드에서 이미지를 가져옵니다. 캐시에 이미지가 남아 있습니다. 당신은뿐만 아니라 SD 카드에서 URL에서 이미지를 얻을 수 있습니다. 이것은 둘 다 작동합니다.

이 클래스를 초기화하고 이미지를 가져 오기만하면됩니다.

imageLoader = new ImageLoader(this); 

그리고 그 방법을 호출하여 sd 카드에서 이미지를 가져 와서 원하는 위치에 사진을 설정하십시오.

public class ImageLoader { 

MemoryCache memoryCache = new MemoryCache(); 
FileCache fileCache; 
private Map<ImageView, String> imageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>()); 
ExecutorService executorService; 
Handler handler = new Handler();// handler to display images in UI thread 

Context mContext; 
boolean imageWithReflection; 

public ImageLoader(Context context) { 
    fileCache = new FileCache(context); 
    executorService = Executors.newFixedThreadPool(5); 
    this.mContext = context; 
    this.stubImageBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.default_image); 
} 

final Bitmap stubImageBitmap; 

public void displayImageFromUrl(String url, ImageView imageView, boolean imageWithReflection) { 
    this.imageWithReflection = imageWithReflection; 
    imageViews.put(imageView, url); 
    Bitmap bitmap = memoryCache.get(url); 
    if (bitmap != null) { 
     if (this.imageWithReflection) 
      imageView.setImageBitmap(createReflectedImage(bitmap)); 
     else 
      imageView.setImageBitmap(bitmap); 
    } else { 
     queuePhoto(url, imageView); 
     if (this.imageWithReflection) 
      imageView.setImageBitmap(createReflectedImage(stubImageBitmap)); 
     else 
      imageView.setImageBitmap(stubImageBitmap); 
    } 
} 

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); 
     ActivityUtils.copyStream(is, os); 
     os.close(); 
     conn.disconnect(); 
     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; 
     FileInputStream stream1 = new FileInputStream(f); 
     BitmapFactory.decodeStream(stream1, null, o); 
     stream1.close(); 

     // 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; 
     FileInputStream stream2 = new FileInputStream(f); 
     Bitmap bitmap = BitmapFactory.decodeStream(stream2, null, o2); 
     stream2.close(); 
     return bitmap; 
    } catch (FileNotFoundException e) { 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    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() { 
     try { 
      if (imageViewReused(photoToLoad)) 
       return; 
      Bitmap bmp = getBitmap(photoToLoad.url); 
      memoryCache.put(photoToLoad.url, bmp); 
      if (imageViewReused(photoToLoad)) 
       return; 
      BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad); 
      handler.post(bd); 
     } catch (Throwable th) { 
      th.printStackTrace(); 
     } 
    } 
} 

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) { 
      if (imageWithReflection) 
       photoToLoad.imageView.setImageBitmap(createReflectedImage(bitmap)); 
      else 
       photoToLoad.imageView.setImageBitmap(bitmap); 
     } else { 
      if (imageWithReflection) 
       photoToLoad.imageView.setImageBitmap(createReflectedImage(stubImageBitmap)); 
      else 
       photoToLoad.imageView.setImageBitmap(stubImageBitmap); 
     } 
    } 
} 

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

private Bitmap createReflectedImage(Bitmap originalImage) { 
    final int reflectionGap = 4; 

    int width = originalImage.getWidth(); 
    int height = originalImage.getHeight(); 

    // This will not scale but will flip on the Y axis 
    Matrix matrix = new Matrix(); 
    matrix.preScale(1, -1); 

    // Create a Bitmap with the flip matrix applied to it. 
    // We only want the bottom half of the image 
    Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0, height/2, width, height/2, matrix, false); 

    // Create a new bitmap with same width but taller to fit reflection 
    Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height/2), Config.ARGB_8888); 

    // Create a new Canvas with the bitmap that's big enough for 
    // the image plus gap plus reflection 
    Canvas canvas = new Canvas(bitmapWithReflection); 
    // Draw in the original image 
    canvas.drawBitmap(originalImage, 0, 0, null); 
    // Draw in the gap 
    Paint deafaultPaint = new Paint(); 
    canvas.drawRect(0, height, width, height + reflectionGap, deafaultPaint); 
    // Draw in the reflection 
    canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null); 

    // Create a shader that is a linear gradient that covers the reflection 
    Paint paint = new Paint(); 
    LinearGradient shader = new LinearGradient(0, originalImage.getHeight(), 0, bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP); 
    // Set the paint to use this shader (linear gradient) 
    paint.setShader(shader); 
    // Set the Transfer mode to be porter duff and destination in 
    paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN)); 
    // Draw a rectangle using the paint with our linear gradient 
    canvas.drawRect(0, height, width, bitmapWithReflection.getHeight() + reflectionGap, paint); 

    return bitmapWithReflection; 
} 

createReflectedImage() 메소드와 같은 추가 코드를 제거하거나 무시하십시오.

관련 문제