ImageView Bild wird unscharf

  • Antworten:9
  • OffenNicht stickyBentwortet
  • Forum-Beiträge: 38

30.09.2018, 13:07:57 via Website

Hallo zusammen,

ich arbeite gerade an einem Spiel mit Pixelgrafik und habe deshalb eine Menge resourcen, die nur ein paar Pixel groß sind.
Das Problem ist, dass, wenn ich diese Resourcen in eine ImageView lade, sie vergrößert und dabei auch geglättet werden, sodass sie auf dem Bildschirm unscharf erscheinen.

In einem Tutorial (http://www.41post.com/4241/programming/android-disabling-anti-aliasing-for-pixel-art) habe ich gelesen, dass man die Resource vorher als Bitmap laden und dann im Code vergrößern kann, um diesen Effekt abzustellen.
Leider funktioniert das bei mir nicht. Egal, wie groß ich die Bitmap skaliere, sie erscheint auf dem Bildschirm immer gleich unscharf. :-(

Ich habe Testweise auch schon meine Resource vergrößert abgespeichert und dann direkt in die ImageView geladen. Da wird das Bild zwar nicht mehr Unscharf, aber ist natürlich keine elegante Lösung, alle Bilder 10 mal so groß abzuspeichern, wie sie eigentlich sind.

        Bitmap bmp = BitmapFactory.decodeResource(getResources(), resId);
        Bitmap bmp2 = Bitmap.createScaledBitmap(bmp, bmp.getWidth() * 10, bmp.getHeight() * 10, false);
        imageView.setImageBitmap(bmp2);
Diskutiere mit!
Beste Antwort
  • Forum-Beiträge: 2.902

30.09.2018, 18:12:00 via Website

Theoretisch kann ich natürlich meine Grafiken direkt in der für den Bildschirm richtigen größe abspeichern,

Und das sollt Du eben nicht, sondern den "nodpi" Ordner verwenden.
Hatte ich allerdings schon oben erwähnt.

Liebe Grüße - Stefan
[ App - Entwicklung ]

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 2.902

30.09.2018, 13:20:17 via Website

Hallo Robert,
um eine genaue Antwort zu geben solltest Du ggf mal Deine Source resp die Destination Dimensionen mitteilen.

Bei einem scheinst du allerdings einen Denkfehler zu machen :
Eine Glättung eines Rasterimages bewirkt nicht die Schärfe , wenn die Destination X-mal grösser ist.
Abhängig von deiner Screen-DPI wirst du natürlich den von dir beschreiben Effekt erhalten.
Eine schlichte Vergrösserung ist nur eine Lupe der eigentlichen Unschärfe.

Desweiteren wird bei der Bitmap-Factory kein decomprimiertes Format im ImageView-Speicher gehalten, sondern nur das File. Erst beim vom System angeforderten Rendering wird dies decomprimert.

Lösen kannst du das nur , wenn du eine genügende Auflösung im nodpi folder anlegst und von dort aus nimmst.

— geändert am 30.09.2018, 13:25:27

Liebe Grüße - Stefan
[ App - Entwicklung ]

Hilfreich?
Diskutiere mit!
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.177

30.09.2018, 13:20:20 via Website

Hallo Robert,

damit ein Bild in der passenden Qualität angezeigt wird, sollte dieses mindestens so Groß (Pixel) sein, dass du dieses ohne Skalierung auf dem Bildschirm anzeigen kannst.
Je mehr du versuchst, ein kleineres Bild auf eine größere Größe zu bekommen, desto mehr Qualitätsverlust hast du.
Somit speichere das Bild so ab, dass es die passende Größe hat.
Am besten du erstellst es gleich so, das es die passende Größe hat und skalierst es nicht im nachhinein höher.

 Alternativ kannst du es mal so probieren:
    static Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth, int orientation) {
            int width = bm.getWidth();
            int height = bm.getHeight();
            float scaleWidth = ((float) newWidth) / width;
            float scaleHeight = ((float) newHeight) / height;
            // create a matrix for the manipulation
            Matrix matrix = new Matrix();
            // resize the bit map
            matrix.postScale(scaleWidth, scaleHeight);
            if (orientation == ExifInterface.ORIENTATION_ROTATE_90) {
                matrix.postRotate(90);
            } else if (orientation == ExifInterface.ORIENTATION_ROTATE_270) {
                matrix.postRotate(270);
            } else if (orientation == ExifInterface.ORIENTATION_ROTATE_180) {
                matrix.postRotate(180);
            } else if (orientation == ExifInterface.ORIENTATION_TRANSPOSE) {
                matrix.postRotate(-90);
            }
            // recreate the new Bitmap
            Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
            return resizedBitmap;
        }

LG Pascal //It's not a bug, it's a feature. :) ;)

Hilfreich?
Robert S., Jokel und 1 mehr Robert S.Jokelswa00
Diskutiere mit!
  • Forum-Beiträge: 38

30.09.2018, 14:31:35 via Website

Das mit der Matrix habe ich ausprobiert, aber leider hat es mir dasselbe Ergebnis gebracht. :-(

Theoretisch kann ich natürlich meine Grafiken direkt in der für den Bildschirm richtigen größe abspeichern, aber dann skaliere ich es halt vor dem abspeichern schon in Photoshop hoch.
Mein Titelbild zum Beispiel ist 72 Pixel breit. Wenn ich es vor dem abspeichern mit Photoshop auf 720 Pixel skaliere und dann meine App angucke ist es scharf. Praktischer wäre aber, wenn ich diesen Schritt des skalierens in meine App verlagern könnte, dann wären die Dateien kleiner und es wäre leichter für mich, mal eben was zu ändern.

Hilfreich?
Diskutiere mit!
Pascal P.
  • Mod
  • Blogger
  • Forum-Beiträge: 10.177

30.09.2018, 14:41:37 via Website

Also auf dem Java Standardweg wirst du da immer Verluste haben.
Was meinst du wieso Android gerade alle xxdpi Ordner für verschiedene Displaygrößen hat?

Du kanst es aber mal mit einer Lib versuchen z.b.:
https://github.com/hkk595/Resizer
Oder sich nach einer anderen Lib umschauen

LG Pascal //It's not a bug, it's a feature. :) ;)

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 38

30.09.2018, 14:58:44 via Website

Hmm, ok, dann werde ich mal schauen, ob es eine Lib gibt, die kann, was ich will.

Das mit den verschiedenen DPI-Ordnern macht natürlich schon Sinn, wenn die Bilder irgendwie geglättet werden sollen oder die Zielgröße kein vielfaches der Startgröße ist. Aber ich will ja im Prinzip nur Pixel kopieren, da dachte ich, dass muss doch irgendwie auch so gehen. :-D

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 484

30.09.2018, 16:36:01 via Website

Hallo mal zur Info Pixel Grafiken die vergrößert werden verlieren immer an Qualität. Das wird dir bei jedem Grafik Bearbeituns Programm beigebracht.
Da kann der beste Algorithmus auch nichts machen. Eine Verzögeru um das 1,5 bis 2 fache ist da meistens noch akzeptabel darüber meistens nicht.

Hilfreich?
Diskutiere mit!
Beste Antwort
  • Forum-Beiträge: 2.902

30.09.2018, 18:12:00 via Website

Theoretisch kann ich natürlich meine Grafiken direkt in der für den Bildschirm richtigen größe abspeichern,

Und das sollt Du eben nicht, sondern den "nodpi" Ordner verwenden.
Hatte ich allerdings schon oben erwähnt.

Liebe Grüße - Stefan
[ App - Entwicklung ]

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 38

30.09.2018, 21:15:09 via Website

Hi swa00,

ich habe mir das mit dem nodpi mal genauer durchgelesen und dann bei mir im Projekt einen "drawable-nodpi"-Ordner angelegt und meine Pixelgrafiken in diesen Ordner geschoben.

Beim direkten setzen von der Resource in die ImageView hatte ich immernoch das Problem mit der verschwommenen Anzeige, aber als ich dann nochmal den Code von meinem ersten Beitrag eingebaut habe (also das mit der "scaledBitmap") hat es tatsächlich so funktioniert, wie ich es haben wollte. (cool)

Jetzt verstehe ich auch, was du mit deinem Satz "Erst beim vom System angeforderten Rendering wird dies decomprimert" gemeint hast. Das Problem war anscheinend, dass er beim erstellen einer Bitmap aus der Resource schon eine skalierte Version bearbeitet hat. ^^

@Jokel
Das was du meinst trifft hier nicht zu. Wenn ich eine Grafik mit zum Beispiel 10x10 Pixeln habe und die Pixelperfekt auf 100x100 Pixel skaliere, geht keine Qualität verloren, weil alles nur kopiert werden muss. Was Anderes wäre es, wenn ich meine 10x10 Pixel auf zum Beispiel 23x23 Pixel bringen will. Hier müsste beim skalieren entschieden werden, was mit den 3 übrigen Pixeln passieren soll, wodurch das Ergebnis wahrscheinlich nicht mehr so schön aussieht.

— geändert am 30.09.2018, 21:18:21

Hilfreich?
Diskutiere mit!
  • Forum-Beiträge: 484

30.09.2018, 22:18:03 via Website

Also wenn ein Bild mit 10x10 auf 100x100 anzeigen willst wird es immer scrallirt und bescheiden aussehen. Oder du hast nur eine Briefmarke Grosses Bild. Aus einem Pixel müssen 10x10 100 Pixel werden kölschen Bildung nicht grade schön.
Deshalb versuchen die sallierungs Algorithmen Pixel dazu zu erfinden auf Grundlage der umgebenen Pixel.
Ein einfaches kopieren findet in den seltensten Fällen statt.

Kann deinen Ausführungen nicht zustimmen das es da keine Qualität verloren geht wie ich schon sagte geht das bis zu einen bestimmten Faktor ganz gut nur bei Faktor 10 glaube ich nicht daran. 3 könnte noch ok sein kommt auf das Bild an.

Es wird nicht nur einfach die Pixel verdoppelt oder der 10 facht.
Das kommt auf den scralieungs Modus an .
Dann mache dich mal über die verschiedenen Modi schlau was da genau unter der Haupt auf pixelebene passiert niemals ein einfaches kopieren. Wenn du dass haben willst musst du das selbermachen. Glaube uns einfach.

— geändert am 30.09.2018, 22:34:27

Hilfreich?
Diskutiere mit!

Empfohlene Artikel