Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/JAVA/Threema/app/src/main/java/ch/threema/app/utils/     Datei vom 25.3.2026 mit Größe 9 kB image not shown  

Quelle  IconUtil.java

  Sprache: JAVA
 

package ch.threema.app.utils;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.media.MediaMetadataRetriever;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Build;
import android.os.CancellationSignal;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;

import org.slf4j.Logger;

import java.io.IOException;

import ch.threema.app.R;
import ch.threema.app.ui.MediaItem;
import static ch.threema.base.utils.LoggingKt.getThreemaLogger;

import static android.media.MediaMetadataRetriever.OPTION_CLOSEST_SYNC;
import static ch.threema.app.services.MessageServiceImpl.THUMBNAIL_SIZE_PX;

public class IconUtil {
    private static final Logger logger = getThreemaLogger("IconUtil");

    public static @DrawableRes int getMimeCategoryIcon(MimeUtil.MimeCategory category) {
        switch (category) {
            case APK:
                return R.drawable.ic_doc_apk;
            case AUDIO:
                return R.drawable.ic_doc_audio;
            case CERTIFICATE:
                return R.drawable.ic_doc_certificate;
            case CODES:
                return R.drawable.ic_doc_codes;
            case COMPRESSED:
                return R.drawable.ic_doc_compressed;
            case CONTACT:
                return R.drawable.ic_doc_contact;
            case DOCUMENT:
                return R.drawable.ic_doc_document;
            case EVENT:
                return R.drawable.ic_doc_event;
            case FOLDER:
                return R.drawable.ic_doc_folder;
            case FONT:
                return R.drawable.ic_doc_font;
            case IMAGE:
                return R.drawable.ic_doc_image;
            case PDF:
                return R.drawable.ic_doc_pdf;
            case PRESENTATION:
                return R.drawable.ic_doc_presentation;
            case SPREADSHEET:
                return R.drawable.ic_doc_spreadsheet;
            case TEXT:
                return R.drawable.ic_doc_text;
            case VIDEO:
                return R.drawable.ic_doc_video;
            case WORD:
                return R.drawable.ic_doc_word;
            case EXCEL:
                return R.drawable.ic_doc_excel;
            case POWERPOINT:
                return R.drawable.ic_doc_powerpoint;
            default:
                return R.drawable.ic_doc_file;
        }
    }

    public static @DrawableRes int getMimeIcon(@Nullable String mimeType) {
        MimeUtil.MimeCategory category = MimeUtil.getMimeCategory(mimeType);
        return getMimeCategoryIcon(category);
    }

    @WorkerThread
    public static @Nullable Bitmap getThumbnailFromUri(Context context, Uri uri, int thumbSize, String mimeType, boolean ignoreExifRotate) {
        logger.debug("getThumbnailFromUri");

        String docId = null;
        long imageId = -1;
        Bitmap thumbnailBitmap = null;
        ContentResolver contentResolver = context.getContentResolver();
        BitmapUtil.ExifOrientation exifOrientation = BitmapUtil.getExifOrientation(context, uri);

        if (!MimeUtil.MIME_TYPE_IMAGE_JPEG.equals(mimeType) && !MimeUtil.MIME_TYPE_IMAGE_PNG.equals(mimeType) && !MimeUtil.MIME_TYPE_IMAGE_HEIF.equals(mimeType) && !MimeUtil.MIME_TYPE_IMAGE_HEIC.equals(mimeType)) {
            if (DocumentsContract.isDocumentUri(context, uri)) {
                // Note: these thumbnails MAY or MAY NOT have EXIF rotation already applied. So we can't use them for JPEG
                Point thumbPoint = new Point(thumbSize, thumbSize);
                try {
                    thumbnailBitmap = DocumentsContract.getDocumentThumbnail(contentResolver, uri, thumbPoint, new CancellationSignal());
                    if (thumbnailBitmap != null) {
                        return thumbnailBitmap;
                    }
                } catch (Exception e) {
                    // ignore - no thumbnail found
                    logger.error("Exception", e);
                }

                // get id from document provider
                docId = DocumentsContract.getDocumentId(uri);
            } else if (ContentResolver.SCHEME_CONTENT.equalsIgnoreCase(uri.getScheme())) {
                docId = uri.getLastPathSegment();
            }

            if (!TestUtil.isEmptyOrNull(docId)) {
                final String[] split = docId.split(":");
                if (split.length >= 2) {
                    final String idString = split[1];

                    if (!TestUtil.isEmptyOrNull(idString)) {
                        try {
                            imageId = Long.parseLong(idString);
                        } catch (NumberFormatException x) {
                            logger.error("Exception", x);
                        }
                    }
                }
            }

            if (imageId == -1) {
                // query media store for thumbnail
                String[] columns = new String[]{MediaStore.Images.Thumbnails._ID};
                try (Cursor cursor = contentResolver.query(uri, columns, nullnullnull)) {

                    if (cursor != null && cursor.moveToFirst()) {
                        imageId = cursor.getInt(cursor.getColumnIndex(MediaStore.Images.Thumbnails._ID));
                    }
                } catch (Exception e) {
                    logger.error("Exception", e);
                }
            }

            logger.debug("Thumbnail image id: {}", imageId);

            if (imageId > 0) {
                // may throw java.lang.SecurityException
                try {
                    thumbnailBitmap = MediaStore.Images.Thumbnails.getThumbnail(contentResolver, imageId, MediaStore.Images.Thumbnails.MINI_KIND, null);
                } catch (Exception e) {
                    logger.error("Exception", e);
                }
            }
        }

        if (thumbnailBitmap == null) {
            // PNGs or GIFs may contain transparency
            boolean mayContainTransparency = MimeUtil.MIME_TYPE_IMAGE_PNG.equals(mimeType) || MimeUtil.MIME_TYPE_IMAGE_GIF.equals(mimeType);
            thumbnailBitmap = BitmapUtil.safeGetBitmapFromUri(context, uri, thumbSize, !mayContainTransparency, truefalse);
        }

        if (thumbnailBitmap == null && MimeUtil.isVideoFile(mimeType)) {
            thumbnailBitmap = getVideoThumbnailFromUri(context, uri);

            if (thumbnailBitmap == null) {
                String path = FileUtil.getRealPathFromURI(context, uri);

                if (path != null) {
                    thumbnailBitmap = ThumbnailUtils.createVideoThumbnail(
                        path,
                        MediaStore.Images.Thumbnails.MINI_KIND);
                }
            }
        }

        if (thumbnailBitmap != null && !ignoreExifRotate && (exifOrientation.getRotation() != 0f || exifOrientation.getFlip() != BitmapUtil.FLIP_NONE)) {
            return BitmapUtil.rotateBitmap(thumbnailBitmap, exifOrientation.getRotation(), exifOrientation.getFlip());
        }

        return thumbnailBitmap;
    }

    @Nullable
    public static Bitmap getVideoThumbnailFromUri(@NonNull Context context, @NonNull Uri uri) {
        // TODO(ANDR-4279): Improve thumbnail extraction
        // do not use automatic resource management on MediaMetadataRetriever
        // noinspection resource
        final MediaMetadataRetriever retriever = new MediaMetadataRetriever();
        try {
            retriever.setDataSource(context, uri);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
                return retriever.getScaledFrameAtTime(1, OPTION_CLOSEST_SYNC, THUMBNAIL_SIZE_PX, THUMBNAIL_SIZE_PX);
            } else {
                final @Nullable Bitmap firstFrame = retriever.getFrameAtTime(1);
                if (firstFrame == null) {
                    logger.error("Failed to get first frame for video thumbnail");
                    return null;
                }
                return BitmapUtil.resizeBitmapExactlyToMaxWidth(firstFrame, THUMBNAIL_SIZE_PX);
            }
        } catch (Exception e) {
            //do not show the exception!
            logger.error("Exception", e);
        } finally {
            try {
                retriever.release();
            } catch (IOException e) {
                logger.debug("Failed to release MediaMetadataRetriever");
            }
        }
        return null;
    }

    @Nullable
    public static Bitmap getVideoThumbnailFromUri(@NonNull Context context, @NonNull MediaItem mediaItem) {
        // TODO(ANDR-4279): Improve thumbnail extraction
        // do not use automatic resource management on MediaMetadataRetriever
        // noinspection resource
        final MediaMetadataRetriever retriever = new MediaMetadataRetriever();
        try {
            retriever.setDataSource(context, mediaItem.getUri());
            final long timeUs = mediaItem.getStartTimeMs() == 0 ? 1L : mediaItem.getStartTimeMs() * 1000;
            final @Nullable Bitmap firstFrame = retriever.getFrameAtTime(timeUs);
            if (firstFrame == null) {
                logger.error("Failed to get first frame for video thumbnail");
                return null;
            }
            // getScaledFrameAtTime() returns unfiltered bitmaps that look bad at low resolutions
            return BitmapUtil.resizeBitmapExactlyToMaxWidth(firstFrame, THUMBNAIL_SIZE_PX);
        } catch (Exception e) {
            // do not show the exception!
            logger.error("Exception", e);
        } finally {
            try {
                retriever.release();
            } catch (IOException e) {
                logger.debug("Failed to release MediaMetadataRetriever");
            }
        }
        return null;
    }
}

Messung V0.5 in Prozent
C=95 H=96 G=95

¤ Dauer der Verarbeitung: 0.17 Sekunden  (vorverarbeitet am  2026-04-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.