Bitmap laden

  • Antworten:9
  • Bentwortet
dwjiidnsw
  • Forum-Beiträge: 58

20.04.2018, 00:00:24 via Website

Hallo,
ich wollte das nach einem Touch Event eine Bitmap geladen wird. (Das ganze soll für eine Sudoku App sein zum Zahlen eingeben). Aber die alte Bitmap verschwindet immer nach einem neuen TouchEvent. Hat wer einen Tip woran das liegt ?

Schonmal danke im Vorraus

  public class ZeichenView extends View implements View.OnTouchListener {


  @Override
   protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    if(touchX != 0 && touchY!=0) {
        int xKoord = 0;
        int yKoord = 0;


        Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.eins);
        canvas.drawBitmap(bm,xKoord*getWidth()/9,yKoord*getWidth()/9,pinsel);            
    }
}

   @Override
   public boolean onTouch(View v, MotionEvent event) {
    int aktion =event.getAction();

    if(aktion == MotionEvent.ACTION_DOWN) {

        touchX = (int) event.getX();
        touchY = (int) event.getY();
        invalidate();
        return true;
     }
     return false;
   }
Kommentieren
Beste Antwort
swa00
  • Forum-Beiträge: 3.704

20.04.2018, 19:09:07 via Website

Ich möchte nun das die Bitmap in das Feld was blau ist, geladen wird, dafür muss ich das canvas ja immer repainten.

Nein musst du nicht , denn diese Vorgehensweise ist viel zu Aufwendig

Einfache Variante :
Du erstellst Dir ImageButtons und weisse/blaue Grafiken in den Resourcen.
Je nachdem, welches Bitmap zu benötigst, setzt du schlichtweg mit setImageDrawable das Gewünschte.

Etwas aufwendiger jedoch flexibel:
Du erstellst Dir Basis PNG's mit 40% AlphaChannel und wechselst zur Laufzeit die Farbe
der View.

Bsp hierzu :

public void setImageDrawableByColor (ImageView v, int Resource, int color)
{
Drawable IconNext;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
IconNext = (Context).getResources().getDrawable(Resource);
else
IconNext = (Context).getResources().getDrawable(Resource,null);
IconNext.mutate().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
v.setImageDrawable(IconNext);
}

— geändert am 20.04.2018, 20:58:13

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

Hilfreich?
dwjiidnsw
Kommentieren
swa00
  • Forum-Beiträge: 3.704

20.04.2018, 08:10:33 via Website

Hallo,

Aber die alte Bitmap verschwindet immer nach einem neuen TouchEvent.

Könntest du bitte mal das im Detail erklären ?

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

Hilfreich?
Kommentieren
Gelöschter Account
  • Forum-Beiträge: 11

20.04.2018, 08:28:35 via Website

Hallo die ondraw Methode wird wohl bei jedem klick Event aufgerufen. Und da du nur immer ein Bitmap auf die canvas schreibst ist das alte nicht mehr sichtbar. Beim Aufruf von ondraw ist canvas immer lehr und du zeichnet nur ein Bitmap.
Entweder du machst eine Schleife wo alle Felder von seinen Sudoku durchlaufen werden oder speicherst deine canvas i ein Bitmap was du bein nächsten Aufruf wieder lädst und dein neues bitmap hinzufügt.

Hilfreich?
Kommentieren
swa00
  • Forum-Beiträge: 3.704

20.04.2018, 08:41:35 via Website

Entweder du machst eine Schleife wo alle Felder von seinen Sudoku durchlaufen werden oder speicherst deine canvas i ein Bitmap was du bein nächsten Aufruf wieder lädst und dein neues bitmap hinzufügt.

Veto : Das lässt ihn vermutlich seinen Speicher überlaufen.

a) Entweder er benutzt dann LruCache
https://developer.android.com/reference/android/util/LruCache.html

b) Oder direkt Glide - (die haben eine Art LRUCache integriert)
https://github.com/bumptech/glide

— geändert am 20.04.2018, 08:42:25

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

Hilfreich?
Kommentieren
Gelöschter Account
  • Forum-Beiträge: 11

20.04.2018, 08:51:04 via Website

Saw00 zu Info ich hatte so etwas schon mal mit einer schleife und 100x100 Felder gemacht und kein Speicher überlaufen.
Natürlich braucht er ein Array wo er seine zahlen speichert und dann in ondraw in einer schleife durchgeht und die entsprechenden bitmaps setzt.

Schön das du auch erkannt hast wo der Fehler ist:-)

Hilfreich?
Kommentieren
swa00
  • Forum-Beiträge: 3.704

20.04.2018, 09:01:40 via Website

Hallo Jogi,

Schön das du auch erkannt hast wo der Fehler ist

Mal so ganz nebenbei :
Deine bisherigen Beiträge haben immer einen gewissen "Du Blödmann" Unterton.

Du bist herzlichst in unserer "Entwickler-Gemeinde" willkommen , jedoch ist das
leider ein Nogo und so etwas sehen wir gar nicht gerne.

Wir beantworten schon des Längeren hier Forenbeiträge und üben die Entwicklung hauptberuflich aus.
Wir wissen schon , was wir an welcher Stelle Schreiben und wie wir die zielführende Beantwortung
"aufbauen" . - Das hat durchaus seinen Sinn !

Wir bitten Dich also, in Zukunft Deine Beiträge ein wenig anzupassen und du musst dich auch
hier nicht profilieren.

Vielen Dank

.

Zurück zum Thema :

a) Der Vorschlag von Glide / LRU hat durchaus seine Berechtigung - die Erfahrung begründet dies.

b) an @dwjiidnsw : Da du eh nur ~ 12 Grafiken hast , und diese recht trivial sind , würde ich gar nicht mit Bitmap arbeiten , auch nicht mit onDraw, sondern schlichtweg nur mit einem ImageView und
setImage() aus den Resourcen zur Laufzeit

— geändert am 20.04.2018, 12:21:36

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

Hilfreich?
Pascal P.
Kommentieren
Gelöschter Account
  • Forum-Beiträge: 11

20.04.2018, 09:19:27 via Website

Er hatte den Code mitgegeben und daraus konnte man erkennen warum das alte bitmap verschwindet.

Hilfreich?
Kommentieren
Tobias E.
  • Forum-Beiträge: 180

20.04.2018, 13:32:39 via Website

Ein paar Ideen dazu:

Wie jogimuc schreibt: Die onDraw() Methode bekommt immer eine leere Canvas übergeben. Alles was Du bei vorherigen Aufrufen drauf gezeichnet hast ist weg.

Wenn Du den grafischen Inhalt der View behalten, und immer nur zusätzliche Dinge drauf zeichnen möchtest, kannst Du Dir selbst eine Bitmap erzeugen die die Größe der View Canvas hat. In onDraw zeichnest Du dann Deine Änderungen auf diese eigene Bitmap, und als letzten Schritt in onDraw dann die eigene Bitmap auf die Canvas. Deine eigene Bitmap wird nie geleert. Somit kannst Du hier nach und nach weitere Grafiken drauf zeichnen, ohne dass die alten verschwinden.

In Deiner onDraw Methode setzt Du die Variablen xKoord und yKoord aktuell immer auf Null. In Deiner canvas.drawBitmap Funktion zeichnest Du das Bild damit immer in die gleiche, linke obere Ecke.

Du erzeugst mit jedem Aufruf der onDraw Methode aktuell die Bitmap bm neu. Das frisst eine Menge Speicher, der dann in einer Garbage Collection Operation freigegeben wird. Das sorgt dann eventuell für Ruckeln oder Hänger in Deiner App. Besser wäre es, die Bitmap bm außerhalb der onDraw Methode einmalig zu erstellen, und dann in der onDraw Methode einfach immer wieder zu verwenden

Hilfreich?
swa00
Kommentieren
dwjiidnsw
  • Forum-Beiträge: 58

20.04.2018, 14:11:52 via Website

Ok,danke. Ich glaube ich hätte es genauer beschreiben müssen.
Meine App bisher: SudokuFeld wird gezeichnet, unten sind 9 buttons mit Zahlen. Wenn man auf ein SudokuFeld tippt färbt es sich blau damit man weiß wo man ist.
Ich möchte nun das die Bitmap in das Feld was blau ist, geladen wird, dafür muss ich das canvas ja immer repainten.

Hilfreich?
Kommentieren
Beste Antwort
swa00
  • Forum-Beiträge: 3.704

20.04.2018, 19:09:07 via Website

Ich möchte nun das die Bitmap in das Feld was blau ist, geladen wird, dafür muss ich das canvas ja immer repainten.

Nein musst du nicht , denn diese Vorgehensweise ist viel zu Aufwendig

Einfache Variante :
Du erstellst Dir ImageButtons und weisse/blaue Grafiken in den Resourcen.
Je nachdem, welches Bitmap zu benötigst, setzt du schlichtweg mit setImageDrawable das Gewünschte.

Etwas aufwendiger jedoch flexibel:
Du erstellst Dir Basis PNG's mit 40% AlphaChannel und wechselst zur Laufzeit die Farbe
der View.

Bsp hierzu :

public void setImageDrawableByColor (ImageView v, int Resource, int color)
{
Drawable IconNext;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP)
IconNext = (Context).getResources().getDrawable(Resource);
else
IconNext = (Context).getResources().getDrawable(Resource,null);
IconNext.mutate().setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
v.setImageDrawable(IconNext);
}

— geändert am 20.04.2018, 20:58:13

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

Hilfreich?
dwjiidnsw
Kommentieren