Android: сканирование каталога и отображение изображений (эскизов) (изображения не хранятся в медиасторе)

Я недавно провел некоторые тесты с изображениями с использованием специальной галереи, которую я разработал с использованием медиа-запросов и медиавеста … Он отлично поработал, но мне действительно нужно что-то делать.

Я не хочу, чтобы фотографии были отсканированы или доступны в медиаторе, поэтому я хотел бы, чтобы мое приложение просматривало каталог и создавало миниатюры и отображало эти миниатюры.

Я нахожу это действительно тонким на земле, чтобы найти примеры хорошего качества для этого.

Может ли кто-нибудь помочь с небольшим примером.

Вот что я ищу.

  1. Картинки хранятся в каталоге SD-карты.
  2. Используя мою собственную галерею, она сканирует этот каталог, но «НЕ» использует медиастар
  3. Мне нужно отобразить содержимое каталога, но, как миниатюры, я предполагаю, что мне нужно будет сначала создать эти миниатюры?
  4. Нажав на thumnail, вы должны получить полноэкранное изображение из моей собственной галереи.

Полагаю, мне просто нужна небольшая помощь в получении изображений из каталога, учитывая, что в нем нет сохраненного mediastore, поэтому я не могу использовать запрос. Другая вещь, которая касается меня, заключается в том, что мне нужно будет создать эскизы для каждого из этих изображений (на лету ??), потому что отображать изображения, но с уменьшенным размером, я бы подозревал, что это будет очень плохо для производительности.

Может ли кто-нибудь помочь?

заранее спасибо

Я сделал то же самое некоторое время назад. Вы должны передать имя папки, где ваши изображения должны быть установлены в setBaseFolder . Этот метод, в свою очередь, вызывает refresh() который – используя FilenameFilter (код не включен, но очень прост в реализации) получает все изображения с именем orig_....jpg из этой папки и удерживает его в mFileList . Затем мы вызываем notifyDataSetChanged() который, в свою очередь, вызывает getView() для каждой ячейки.

Теперь, в getView() мы либо getView() растровое изображение миниатюр из кеша, если у нас его уже есть, иначе мы создаем серый заполнитель и запускаем ThumbnailBuilder для создания эскизов или. Получить растровое изображение.

Я думаю, вам придется немного изменить ThumbnailBuilder , потому что я создаю довольно большие «миниатюры» (500×500), поскольку мне нужны изображения с измененным размером для других целей. Кроме того, когда я работаю с фотографиями, снятыми камерой, там есть кое-что, вращающее изображение в соответствии с информацией exif. Но в основном, ThumbnailBuilder просто проверяет, есть ли уже миниатюрный образ (мои эскизы размещены в одной папке, но имеют префикс small_ вместо orig_ ) – если эскиз уже существует, мы получаем его как Bitmap и выполняем его, иначе Создается изображение. Наконец, в onPostExecute() растровое изображение установлено в ImageView.

 public class PhotoAdapter extends BaseAdapter { private Context mContext; private int mCellSize; private File mFolder; private File[] mFileList; private Map<Object, Bitmap> mThumbnails = new HashMap<Object, Bitmap>(); private Set<Object> mCreatingTriggered = new HashSet<Object>(); // flag that creating already triggered public PhotoAdapter(Context context, int cellSize) { mContext = context; mCellSize = cellSize; } @Override public int getCount() { if (mFolder == null) { return 0; // don't do this } else { return mFileList.length; } } @Override public Object getItem(int position) { return mFileList[position]; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ImageView view = (ImageView)convertView; if (view == null) { view = new ImageView(mContext); view.setLayoutParams(new GridView.LayoutParams(mCellSize, mCellSize)); view.setScaleType(ImageView.ScaleType.CENTER_CROP); view.setPadding(8, 8, 8, 8); view.setBackgroundColor(0xFFC6CCD3); } Object item = getItem(position); Bitmap bm = mThumbnails.get(item); if (bm == null) { view.setImageBitmap(null); if (!mCreatingTriggered.contains(item)) { mCreatingTriggered.add(item); new ThumbnailBuilder(view, (File)item).execute(); } } else { view.setImageBitmap(bm); } return view; } public void setBaseFolder(File baseFolder) { if (baseFolder == null) return; if (!baseFolder.equals(mFolder)) { releaseThumbnails(); mFolder = baseFolder; } refresh(); } public void refresh() { if (mFolder == null) { return; } mFileList = mFolder.listFiles(EtbApplication.origImageFilenameFilter); if (mFileList == null) mFileList = new File[0]; notifyDataSetChanged(); } public void releaseThumbnails() { for (Bitmap bm : mThumbnails.values()) { bm.recycle(); } mThumbnails.clear(); } // ------------------------------------------------------------------------------------ Asynchronous Thumbnail builder private class ThumbnailBuilder extends AsyncTask<Void, Integer, Bitmap> { private ImageView mView; private File mFile; public ThumbnailBuilder(ImageView view, File file) { mView = view; mFile = file; } @Override protected Bitmap doInBackground(Void... params) { Log.d("adapter", "make small image and thumbnail"); try { return createThumbnail(mFile.getAbsolutePath()); } catch (Exception e) { return null; } } @Override protected void onPostExecute(Bitmap result) { if (result != null) { mView.setImageBitmap(result); mThumbnails.put(mFile, result); } else { mView.setImageResource(R.drawable.ic_launcher); } } /** * Creates Thumbnail (also rotates according to exif-info) * @param file * @return * @throws IOException */ private Bitmap createThumbnail(String file) throws IOException { File thumbnailFile = new File(file.replace("orig_", "small_")); // If a small image version already exists, just load it and be done. if (thumbnailFile.exists()) { return BitmapFactory.decodeFile(thumbnailFile.getAbsolutePath()); } // Decode image size BitmapFactory.Options bounds = new BitmapFactory.Options(); bounds.inJustDecodeBounds = true; BitmapFactory.decodeFile(file, bounds); if ((bounds.outWidth == -1) || (bounds.outHeight == -1)) return null; int w, h; if (bounds.outWidth > bounds.outHeight) { // Querformat w = 500; h = 500 * bounds.outHeight / bounds.outWidth; } else { // Hochformat h = 500; w = 500 * bounds.outWidth / bounds.outHeight; } BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inSampleSize = 4; // resample -- kleiner aber noch nicht die 500 Pixel, die kommen dann unten Bitmap resizedBitmap = BitmapFactory.decodeFile(file, opts); resizedBitmap = Bitmap.createScaledBitmap(resizedBitmap, w, h, true); ExifInterface exif = new ExifInterface(file); String orientString = exif.getAttribute(ExifInterface.TAG_ORIENTATION); int orientation = orientString != null ? Integer.parseInt(orientString) : ExifInterface.ORIENTATION_NORMAL; int rotationAngle = 0; if (orientation == ExifInterface.ORIENTATION_ROTATE_90) rotationAngle = 90; if (orientation == ExifInterface.ORIENTATION_ROTATE_180) rotationAngle = 180; if (orientation == ExifInterface.ORIENTATION_ROTATE_270) rotationAngle = 270; Matrix matrix = new Matrix(); matrix.setRotate(rotationAngle, (float) resizedBitmap.getWidth() / 2, (float) resizedBitmap.getHeight() / 2); Bitmap rotatedBitmap = Bitmap.createBitmap(resizedBitmap, 0, 0, w, h, matrix, true); resizedBitmap.recycle(); ByteArrayOutputStream bytes = new ByteArrayOutputStream(); rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 90, bytes); thumbnailFile.createNewFile(); FileOutputStream fo = new FileOutputStream(thumbnailFile); fo.write(bytes.toByteArray()); fo.close(); //new File(file).delete(); // Originalbild löschen return rotatedBitmap; } } }