Implementierung des KenBurns-Effekts auf Android mit dynamischer Bitmap-Einstellung

Hintergrund

Ich arbeite an einer Umsetzung der "KenBurns-Effekt"(DemoHier) in der Aktionsleiste, wie auf gezeigtdiese BibliothekBeispiel (außer dem bewegten Symbol, das ich selbst gemacht habe).

Tatsächlich habe ich schon vor langer Zeit danach gefragt (Hier), dessen Namen ich zu diesem Zeitpunkt noch nicht einmal kannte. Ich war mir sicher, dass ich eine Lösung gefunden habe, aber es gibt einige Probleme.

Da ich manchmal die Bilder vom Gerät zeige, müssen einige sogar gedreht werden, sodass ich ein rotatableDrawable verwende (wie gezeigt)Hier).

Das Problem

Die aktuelle Implementierung kann nicht mit mehreren Bitmaps umgehen, die dynamisch angegeben werden (z. B. aus dem Internet), und es wird nicht einmal die Größe der Eingabebilder überprüft.

Stattdessen wird nur zufällig gezoomt und übersetzt, sodass vielfach zu viel oder zu wenig gezoomt und leere Bereiche angezeigt werden können.

Der Code

Hier ist der Code, der mit den Problemen zusammenhängt:

private float pickScale() {
    return MIN_SCALE_FACTOR + this.random.nextFloat() * (MAX_SCALE_FACTOR - MIN_SCALE_FACTOR);
}

private float pickTranslation(final int value, final float ratio) {
    return value * (ratio - 1.0f) * (this.random.nextFloat() - 0.5f);
}

public void animate(final ImageView view) {
    final float fromScale = pickScale();
    final float toScale = pickScale();
    final float fromTranslationX = pickTranslation(view.getWidth(), fromScale);
    final float fromTranslationY = pickTranslation(view.getHeight(), fromScale);
    final float toTranslationX = pickTranslation(view.getWidth(), toScale);
    final float toTranslationY = pickTranslation(view.getHeight(), toScale);
    start(view, KenBurnsView.DELAY_BETWEEN_IMAGE_SWAPPING_IN_MS, fromScale, toScale, fromTranslationX,
            fromTranslationY, toTranslationX, toTranslationY);
}

Und hier ist der Teil der Animation selbst, der die aktuelle ImageView animiert:

private void start(View view, long duration, float fromScale, float toScale, float fromTranslationX, float fromTranslationY, float toTranslationX, float toTranslationY) {
    view.setScaleX(fromScale);
    view.setScaleY(fromScale);
    view.setTranslationX(fromTranslationX);
    view.setTranslationY(fromTranslationY);
    ViewPropertyAnimator propertyAnimator = view.animate().translationX(toTranslationX).translationY(toTranslationY).scaleX(toScale).scaleY(toScale).setDuration(duration);
    propertyAnimator.start();
}

Wie Sie sehen können, werden die Ansichts- / Bitmap-Größen nicht berücksichtigt, und es wird nur nach dem Zufallsprinzip ausgewählt, wie gezoomt und geschwenkt werden soll.

Was ich versucht habe

Ich habe dafür gesorgt, dass es mit dynamischen Bitmaps funktioniert, aber ich verstehe nicht, was ich daran ändern soll, damit es die Größen richtig handhabt.

Ich habe auch bemerkt, dass es eine andere Bibliothek gibt (Hier) das funktioniert, hat aber auch die gleichen Probleme, und es ist noch schwerer zu verstehen, wie man sie dort behebt. Außerdem stürzt es zufällig ab.Hier ist Ein Beitrag, den ich darüber berichtet habe.

Die Frage

Was ist zu tun, um den Ken-Burns-Effekt korrekt zu implementieren, damit dynamisch erstellte Bitmaps verarbeitet werden können?

Ich denke, dass die beste Lösung vielleicht darin besteht, die Art und Weise anzupassen, in der ImageView seinen Inhalt zeichnet, sodass zu einem bestimmten Zeitpunkt ein Teil der Bitmap angezeigt wird, die ihm zugewiesen wurde, und die eigentliche Animation zwischen zwei Rechtecken liegt der Bitmap. Leider bin ich mir nicht sicher, wie ich das machen soll.

Auch hier geht es nicht darum, Bitmaps zu erhalten oder zu dekodieren. Es geht darum, wie sie mit diesem Effekt gut funktionieren, ohne Abstürze oder seltsames Vergrößern / Verkleinern, wodurch leere Räume angezeigt werden.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage