立即扫描大图像

问题描述:

我开发了一个带滑动图像功能的画廊应用程序(向左/向右拖动并出现新的全屏图像)。 问题是,我没有成功克服大图像的小延迟,直到它们出现(Whatsapp图像 - 没有问题,相机图像不像在内置图库应用程序中那样平滑)。 我尝试了几种重新调整大小/解码图像的方法,但仍然存在延迟。立即扫描大图像

我的代码:

FullScreenImageAdapter.java

public class FullScreenImageAdapter extends PagerAdapter { 

private Activity _activity; 
private ArrayList<String> _imagePaths; 
private LayoutInflater inflater; 
private final int IMAGE_MAX_SIZE = 800; 

// constructor 
public FullScreenImageAdapter(Activity activity, 
           ArrayList<String> imagePaths) { 
    this._activity = activity; 
    this._imagePaths = imagePaths; 
} 

@Override 
public int getCount() { 
    return this._imagePaths.size(); 
} 

@Override 
public boolean isViewFromObject(View view, Object object) { 
    return view == ((RelativeLayout) object); 
} 

@Override 
public Object instantiateItem(ViewGroup container, int position) { 
    ImageView imgDisplay; 

    inflater = (LayoutInflater) _activity 
      .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View viewLayout = inflater.inflate(R.layout.layout_fullscreen_image, container, 
      false); 

    imgDisplay = (ImageView) viewLayout.findViewById(R.id.imgDisplay); 

    Bitmap bitmap = decodeSampledBitmapFromPath(_imagePaths.get(position),1000,1000); 

    imgDisplay.setImageBitmap(bitmap); 

    ((ViewPager) container).addView(viewLayout); 

    return viewLayout; 
} 

@Override 
public void destroyItem(ViewGroup container, int position, Object object) { 
    ((ViewPager) container).removeView((RelativeLayout) object); 

} 

public static Bitmap decodeSampledBitmapFromPath(String path, int reqWidth, 
               int reqHeight) { 

    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeFile(path, options); 

    options.inSampleSize = calculateInSampleSize(options, reqWidth, 
      reqHeight); 

    // Decode bitmap with inSampleSize set 
    options.inJustDecodeBounds = false; 
    Bitmap bmp = BitmapFactory.decodeFile(path, options); 
    return bmp; 
} 

public static int calculateInSampleSize(BitmapFactory.Options options, 
             int reqWidth, int reqHeight) { 

    final int height = options.outHeight; 
    final int width = options.outWidth; 
    int inSampleSize = 1; 

    if (height > reqHeight || width > reqWidth) { 
     if (width > height) { 
      inSampleSize = Math.round((float) height/(float) reqHeight); 
     } else { 
      inSampleSize = Math.round((float) width/(float) reqWidth); 
     } 
    } 
    return inSampleSize; 
} 

}

FullScreenViewActivity.java

public class FullScreenViewActivity extends Activity{ 

private FullScreenImageAdapter adapter; 
private ViewPager viewPager; 
int selectedFilePosition; 
String imageFolder; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_full_screen_view); 

    //geting the selected image from the intent 
    /* Getting ImageURI from Gallery from Main Activity */ 
    Uri selectedImgUri = getIntent().getData(); 
    if (selectedImgUri!=null) { 
     imageFolder = getRealPathFromURI(this, selectedImgUri); 
    } 

    viewPager = (ViewPager) findViewById(R.id.pager); 

    adapter = new FullScreenImageAdapter(FullScreenViewActivity.this, getFilePaths(imageFolder)); 

    viewPager.setAdapter(adapter); 

    // displaying selected image first 
    viewPager.setCurrentItem(selectedFilePosition); 
} 

// Reading file paths from SDCard 
public ArrayList<String> getFilePaths(String selectedFilePath) { 
    ArrayList<String> filePaths = new ArrayList<String>(); 

    File file = new File(selectedFilePath); 
    File directory = file.getParentFile(); 

    // check for directory 
    if (directory.isDirectory()) { 
     // getting list of file paths 
     File[] listFiles = directory.listFiles(); 

     // Check for count 
     if (listFiles.length > 0) { 
       // loop through all files 
       for (int i = 0; i < listFiles.length; i++) { 
        // get file path 
        String filePath = listFiles[i].getAbsolutePath(); 
        //set position if this is the required image to show 
        if (filePath.equals(selectedFilePath)) { 
         selectedFilePosition = i; 
         // Add image path to array list 
         filePaths.add(filePath); 
        } 
       } 
     } 

    } 
    return filePaths; 
} 

public String getRealPathFromURI(Context context, Uri contentUri) { 
    Cursor cursor = null; 
    try { 
     String[] proj = { MediaStore.Images.Media.DATA }; 
     cursor = context.getContentResolver().query(contentUri, proj, null, null, null); 
     int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
     cursor.moveToFirst(); 
     return cursor.getString(column_index); 
    } finally { 
     if (cursor != null) { 
      cursor.close(); 
     } 
    } 
} 

}

为了提高性能,您需要另一个线程来加载它的异步。以下是第三方库(Picasso,Glide),您可以在处理大图像时使用这些库。

我也会使用毕加索将图像加载到ImageView中。如果加载一次,则Picasso缓存图像。要预加载一些元素,您可以使用Consumner/Producer Pattern!示例here

+0

我实现了毕加索,性能略胜一筹,但我认为问题在于预加载的图像数量。 – Andy

+0

目前,viewpager正在加载所需图像并预加载另外2个图像(一个位于所需图像的左侧和另一个的右侧)。滑动至预加载的图像会有所反应,但在向相同方向滑动数次时会出现问题。有没有一种方法可以通过viewpager自动预载2个以上的图像? – Andy