how can I use gif's in android mode?

edited July 2016 in Android Mode

Hi everyone !!

I need with the gif's in android mode. GifAnimation library is not working on adroid mode. I have tried running my on android. It works on PC but crashes at start on android. Here's an example :

import gifAnimation.*;

Gif loopingGif;

public void setup() {
  size(400, 200);

  loopingGif = new Gif(this, "lavalamp.gif");
  loopingGif.loop();
}

void draw() {
  background(255);
  image(loopingGif, 10, 10);
}

I have coded the entire thing but it dosent works on android.. Need some suggetions.

Thanks a lot !

Tagged:

Answers

  • @SuyashN=== for that you can use the android web view class with an html+gif

  • @akenton I have written the code for a full game on processing. The code I wrote above is just the example to show my problem. What I am doin is a lot more then just playing the gif. So I need a solution to run the gif on android using Processing's android mode...

  • @akenaton I was working in an example but I couldn't get it to run. This is the line I am using to execute following details from *** WebView ***:

    String gifimg= "<html><body><img src=\"C:/Users/C/Documents/Processing/CMsketches/Android-code/AndroidSpinnerSeekBar/data/lavalamp.gif\" alt=\"This will display an animated GIF\" /></body></html>";
    webview.loadData(gifimg, "text/html", null);
    

    When I execute the application, it doesn't seem to load the gift. Instead, in the webview it shows a boxed msg: "This will display an animated GIF" with a broken generic icon pic in the upper left corner.

    Any suggestions of how to get it to display?

    Kf

  • @SuuyahN=== i dont understand:i answered to your question! - for using gif in android mode: : webview class + html... @kfrager: normally in android "native" you have to put your html (with the gif) in the assets folder; never tried with P5 but try yourself!!! (dont forget to add some line of code on the html head in order to adapt to viewport):: code example from an app i have published::

     mWebView = (WebView) findViewById(R.id.webview);// cannot be used with P5
                   mWebView.getSettings().setJavaScriptEnabled(true);
                    mWebView.loadUrl("file:///android_asset/www/vinyl.html"); //gif animé
    
  • @akenaton I was able to compile the program but I have to save the .gif file in my android storage manually before running the sketch. Originally I have placed my gif file in my data folder within my sketch folder, as usual. However the problem rises when you load the gif in webview. When you call

    mWebView.loadUrl("file:///android_asset/www/vinyl.html");

    I am not sure if loadUrl knows where the android asset folder is located. However if I provided a full path directing to a known location on my phone, it works.

    So I have a question for you: Is it possible to retrieve the full path of the android_asset folder? I think that will solve the problem.

    @SuyashN Can you tell us more abut your problem? What other things do you do with your gif files?

    Kf

  • @akenaton Never mind... your line works:

    webview.loadUrl("file:///android_asset/lavalamp.gif");

    I thought this line would work only from eclipse but I did not know I could use it for processing. Here it is the sample code and ensure your gif file is within your sketch folder in the data folder:

    import android.app.Activity;
    import android.content.Context;
    import android.widget.FrameLayout;
    import android.view.ViewParent;
    import android.widget.RelativeLayout;
    import android.text.Editable;
    import android.graphics.Color;
    import android.widget.Toast;
    import android.os.Looper;
    import android.view.WindowManager;
    import android.view.inputmethod.InputMethodManager;
    import android.os.Bundle;
    import android.os.Environment;
    import android.view.View;
    import android.view.ViewGroup;
    
    import   android.webkit.WebView;
    
    Activity act;
    FrameLayout fl;
    
    WebView webview; 
    
    @Override 
      public void onStart() {
      super.onStart();
    
      act = this.getActivity();
    
      webview = new WebView(act);
      webview.setLayoutParams(new RelativeLayout.LayoutParams( 800, 400 ));
      webview.setX(800);
      webview.setY(600);
      webview.getSettings().setJavaScriptEnabled(true);
    
      webview.loadUrl("file:///android_asset/lavalamp.gif");
    
      fl = (FrameLayout)act.findViewById(0x1000);
      fl.addView(webview);
    }
    
    
    void settings() {
      fullScreen();
    }
    
    void setup() {   
      orientation(LANDSCAPE);
      background(255, 0, 0);
    }
    
    void draw() {
    }
    

    I hope this helps,

    Kf

  • edited July 2016

    @kfrajer i have developed a game which uses gif to show its elements animated. I used the gifAnimation library by Patrick Meister to load and play the animation. It worked fine in java mode but crashes on start in android mode. This is the entire code:

    import gifAnimation.*;
    //
    
    
    PImage bg;
    PImage again;
    PImage next;
    PImage exit;
    PImage unattempted;
    PImage fail;
    PImage hit;
    
    Gif swimmer;
    Gif shark;
    Gif kill;
    int startTime; 
    int currentTime;
    int scoreCount;
    
    int level;
    
    int sharkNum;
    int randomPerRow;
    int time;
    Gif[] cage;
    Gif[] cageEmp;
    PVector[] cagePos;
    boolean [] swimmerKillCheck;
    int attempts;
    int missedAttemptCount;
    boolean attempted;
    PVector[][] gridPoints;
    PVector[] scoreGridPoints;
    int score[];
    PVector[] sharkPos;
    //int sharkDispCount;
    int[] alive;
    boolean[] miss;
    int[] ropeLen;
    int[] ropeLenChng;
    int[] ropeLenTop;
    int[] ropeTopChng;
    
    //Gif[] kill = new Gif[sharkNum];
    
    //int missRopeLen;
    //int missRopeLenChng;
    //int missRopeTop;
    //int missRopeTopChng;
    //int[] ropeTop = new int[sharkNum];
    //int[] ropeTopChng = new int[sharkNum];
    
    void setup()
    {
    
      orientation(LANDSCAPE);
      size(displayWidth, displayHeight);
      //size(620, 380);
      //frameRate(100);
      level = 1;
      startTime = millis(); //do this first thing in setup
      currentTime = 0;
    
    
    
      restart();
    
    
    
      bg = loadImage("bg.png");
      again = loadImage("play again.png");
      next = loadImage("next level.png");
      exit = loadImage("exit.png");
      hit = loadImage("hit.png");
      fail = loadImage("miss.png");
      unattempted = loadImage("empscore.png");
    
      bg.resize(width, height);
      swimmer = new Gif(this, "swimmer.gif");
      swimmer.loop();
    
      shark = new Gif(this, "shark.gif");
    
      //shark.noLoop();
      shark.ignoreRepeat();
      shark.play();
    
      kill = new Gif(this, "kill.gif");
      kill.play();
      //  kill.ignoreRepeat();
    
    
    
    
    
    
    
    
    
      //cage.loop();
      //for (int i=0; i<sharkNum; i++) {
      //  kill[i] = new Gif(this, "kill.gif");
      //    kill[i].ignoreRepeat();
    
    
      //}
      kill = new Gif(this, "kill.gif");
    
    
      //kill.ignoreRepeat();
      //kill.play();
      //kill.noLoop();
    
    
    
    
    
    
      //sharkPos[1].set(150,0);
    
      //println(sharkPos);
    }
    
    
    
    void draw()
    {
      // kill.play();
      // kill.ignoreRepeat();
      image(bg, 0, 0);
      //background(255, 255, 255);
      strokeWeight(3);
    
    
    
      for (int i = 0; i < sharkNum; i ++ ) {
        //for (float j = 2; j <= 2 + (2*sharkNum) + (sharkNum * 35); j = j + 35 + 2) {
        image(unattempted, scoreGridPoints[i].x, scoreGridPoints[i].y);
        //point(scoreGridPoints[i].x, scoreGridPoints[i].y);
    
        // i++;
      }
    
    
      //line(150, 0, 150, height);
      //line(.75*width, 0, .75*width, height);
      //line(0, .05*height, width, .05*height);
      //line(0, .75*height, width, .75*height);
      //image(swimmer,0,0);
      //kill.play();
      //image(kill,-65,-50);
    
    
      for (float i = .05*height; i <= .75*height; i = i + .70*height/(sharkNum-1)) {
        //int iNum = 0;
        for (float j = 150; j <= .75*width; j = j + (.75*width-150)/(randomPerRow-1)) {
    
          //int jNum = 0;
          stroke(0);
          noFill();
    
          //gridPoints[iNum][jNum] = new PVector();
          //gridPoints[iNum][jNum].set(j,i);
          point(j, i);
    
          //println(gridPoints[iNum][jNum]);
    
          //jNum ++;
        }
        //iNum ++;
      }
    
      currentTime = millis() - startTime;
      if (currentTime <= 5500) { 
        for (int i=0; i<sharkNum; i++) {
          image(swimmer, sharkPos[i].x, sharkPos[i].y);
          // shark.resize(200,swimmer.height);0
          image(shark, sharkPos[i].x-150, sharkPos[i].y+10);
          stroke(255, 0, 0);  
          point(sharkPos[i].x-120, sharkPos[i].y+10);
          point(sharkPos[i].x-120+100, sharkPos[i].y+10);
          point(sharkPos[i].x-120, sharkPos[i].y+10+39);
          point(sharkPos[i].x-120+100, sharkPos[i].y+10+39);
        }
      }
    
    
      stroke(66, 112, 108);
      //stroke(255, 0, 0);
      currentTime = millis() - startTime;
      if (currentTime > 5500) { 
    
        //  for (int i=0; i<sharkNum; i++) {
        if (attempts < sharkNum) {
          if (attempted && !miss[attempts]) { 
            if (ropeLenChng[attempts] == 0) {
              ropeLenChng[attempts] = 6;
            }
    
            line(cagePos[attempts].x, 0, cagePos[attempts].x, ropeLen[attempts]);
            image(cageEmp[attempts], cagePos[attempts].x-41, ropeLen[attempts]-38);
            // rect(sharkPos[i].x,sharkPos[i].y,10,10);
    
            if (ropeLen[attempts] > cagePos[attempts].y) {
              ropeLenChng[attempts] = -1*ropeLenChng[attempts];
              cageEmp[attempts] = cage[attempts];
            }
            ropeLen[attempts] = ropeLen[attempts] + ropeLenChng[attempts] ;
            // println(ropeLen);
          }
        }
      }
      // }
    
      if (attempts < sharkNum) {
        if (miss[attempts] && attempted) {
    
    
    
          if (ropeLenChng[attempts] == 0) {
            ropeLenChng[attempts] = 6;
          }
    
          if (ropeLenTop[attempts] <= cagePos[attempts].y) {
            line(cagePos[attempts].x, ropeLenTop[attempts], cagePos[attempts].x, ropeLen[attempts]);
          }
          if (ropeLen[attempts] <= cagePos[attempts].y) {
            image(cageEmp[attempts], cagePos[attempts].x-41, ropeLen[attempts]-38);
            // rect(sharkPos[i].x,sharkPos[i].y,10,10);
          }
    
    
          if (ropeLen[attempts] > cagePos[attempts].y) {
            ropeLenChng[attempts] = 0;
            ropeTopChng[attempts] = 6;
          }
          //if (ropeLenTop[attempts] > cagePos[attempts].y) {
    
          //  ropeTopChng[attempts] = 0;
          //}
          // missRopeTopChng[attempts] = 5;
          //missRopeLen = missRopeLen + missRopeLenChng ;
          ropeLen[attempts] = ropeLen[attempts] + ropeLenChng[attempts] ; 
          ropeLenTop[attempts] = ropeLenTop[attempts] + ropeTopChng[attempts] ;
        }
      }
    
    
    
    
    
      if (attempts >= sharkNum-1) {
    
        currentTime = millis() - startTime;
        if (currentTime < time + 2050) {
          for (int i = 0; i < sharkNum; i++) {
    
            if (swimmerKillCheck[i]) {
              //  rect(sharkPos[i].x, sharkPos[i].y, 10, 10);
              //  kill.play();
              //kill[i].ignoreRepeat();
              image(kill, sharkPos[i].x-65, sharkPos[i].y-50);
            }
          }
        }
      }
    
      currentTime = millis() - startTime;
      if (currentTime > time + 2500 && attempts >= sharkNum-1) {
        if (missedAttemptCount > 0) {
          image(again, width/2 - 80, height/2 - 66);
          image(exit, width/2 - 80, height/2 +10);
          text(attempts+1 + " loose", width/2, height/2);
        } else {
          image(next, width/2 - 80, height/2 - 66);
          image(exit, width/2 - 80, height/2 +10);
          text(attempts+1 + " win", width/2, height/2);
        }
      }
      //kill.play();
      //kill.ignoreRepeat();
      // kill.play();
      if (attempts >= sharkNum) {
        text(attempts+1, width/2, height/2);
      }
    
      for (int i = 0; i < sharkNum; i ++) {
        if (score[i] == 1) {
          image(hit, scoreGridPoints[i].x, scoreGridPoints[i].y);
        }
    
        if (score[i] == 0) {
          image(fail, scoreGridPoints[i].x, scoreGridPoints[i].y);
        }
      }
    
    
      fill(255, 0, 0);
      stroke(255, 0, 0);
    
    
      fill(0, 0, 0);
      textSize(56);
      //Shows Mouse X and Y in bottom left
      text(mouseX + ", " + mouseY, 25, 970);
    }
    
    void mousePressed() {
    //println("time is" + time);
      currentTime = millis() - startTime;
      if (currentTime > 5500)
      {
        if (attempted) {
          attempts = attempts + 1;
        }
    
        for (int i=0; i<sharkNum; i++) {
    
    
    
    
    
          if (sharkPos[i].x-120 < mouseX && mouseX < sharkPos[i].x-120+100 && sharkPos[i].y+10 < mouseY && mouseY < sharkPos[i].y+10+39 && alive[i] == 1 && attempts <= sharkNum)
          {
    
            alive[i] = 0;
            cage[attempts].loop();
            cagePos[attempts] = new PVector();
            cagePos[attempts].set(mouseX, mouseY);
            //cage[i].ignoreRepeat();
            miss[attempts] = false;
            swimmerKillCheck[i] = false;
            score[scoreCount] = 1;
            scoreCount++;
          }
        }
    
        attempted = true;
    
        if (attempts < sharkNum)
        {
          if (miss[attempts]) {
            cagePos[attempts] = new PVector();
            cagePos[attempts].set(mouseX, mouseY);
            missedAttemptCount ++;
    
            score[scoreCount] = 0;
            scoreCount++;
    
    
            //alive[i]=2;
          }
        }
      }
      //println(attempts + "  " + attempted);
    
      currentTime = millis() - startTime;
      //println(currentTime);
    
        if (attempts >= sharkNum-1) {
        if (time == 0) {
          currentTime = millis() - startTime;
          time = currentTime;  
          //println("T" + time);
          //delay(2000);
          kill.stop();  
          kill.play();
        }
    
      if (currentTime > time + 2550) {
        //println("time is" + time);
        //println("chk");
        if (mouseX >= width/2 - 80 && mouseX <= width/2 - 80 + 160 && mouseY >= height/2 + 10 && mouseY <= height/2 + 10 + 56) {
          exit();
        } else if (mouseX >= width/2 - 80 && mouseX <= width/2 - 80 + 160 && mouseY >= height/2 + 10 - 66 && mouseY <= height/2 + 10 + 56 - 66) {
    
          if (missedAttemptCount > 0) {
            restart();
          } else {
            level ++;
    
            restart();
          }
        }
      }
        }
    }
    
    void restart() {
    
      currentTime = 0;
      startTime = millis();
    
      scoreCount = 0;
      sharkNum = level + 2;
      randomPerRow = 5;
      time = 0;
      cage = new Gif[sharkNum];
      cageEmp = new Gif[sharkNum];
      for (int i=0; i<sharkNum; i++) {
        cage[i] = new Gif(this, "cage.gif");
        cageEmp[i] = new Gif(this, "cageEmp.gif");
      }
      cagePos = new PVector[sharkNum];
      swimmerKillCheck = new boolean[sharkNum];
      for (int i = 0; i < sharkNum; i++) {
        swimmerKillCheck[i] = true;
      }
      attempts = 0;
      missedAttemptCount = 0;
      attempted = false;
      gridPoints = new PVector[randomPerRow][sharkNum];
      scoreGridPoints = new PVector[sharkNum];
      sharkPos = new PVector[sharkNum];
      //sharkDispCount = 0;
      alive = new int[sharkNum];
      miss = new boolean[sharkNum];
      for (int i = 0; i < sharkNum; i++) {
        miss[i] = true;
      }
      ropeLen = new int[sharkNum];
      ropeLenChng = new int[sharkNum];
      ropeLenTop = new int[sharkNum];
      ropeTopChng = new int[sharkNum];
    
      score = new int[sharkNum];
    
      //shark.stop();
      shark = new Gif(this, "shark.gif");
      //shark.noLoop();
      shark.play();
      shark.ignoreRepeat();
    
      int iNum = 0;
      int jNum = 0;
      for (float i = .05*height; i <= .75*height; i = i + .70*height/(sharkNum-1)) {
        jNum = 0;
        for (float j = 150; j <= .75*width; j = j + (.75*width-150)/(randomPerRow-1)) {
    
    
          stroke(0);
          noFill();
    
          gridPoints[jNum][iNum] = new PVector();
          gridPoints[jNum][iNum].set(j, i);
          //point(j, i);
    
          // println(jNum  +  "  "  +  iNum + "  "  +  gridPoints[jNum][iNum]);
    
          jNum ++;
        }
        iNum ++;
      }
    
    
      float j = 2;
      for (int jScoreNum = 0; jScoreNum<sharkNum; jScoreNum ++ ) {
        //for (float j = 2; j <= 2 + (2*sharkNum) + (sharkNum * 35); j = j + 35 + 2) {
    
    
        stroke(255);
        noFill();
    
        scoreGridPoints[jScoreNum] = new PVector();
        scoreGridPoints[jScoreNum].set(j, 2);
        score[jScoreNum] = 2;
        //point(j, 2);
    
        j = j + 35 + 2;
        // println(jNum  +  "  "  +  iNum + "  "  +  gridPoints[jNum][iNum]);
    
        //jScoreNum ++;
        //println(scoreGridPoints);
      }
    
    
    
      //gap = displayHeight/sharkNum;
    
      for (int i=0; i < sharkNum; i++) {
        sharkPos[i] = new PVector();
        sharkPos[i].set(gridPoints[int(random(0, randomPerRow-1))][i].x, gridPoints[0][i].y);
        alive[i] = 1;
        //sharkPos[i] = PVector.random2D();
      }
    }
    

    Basically in this code as you can see I am displaying the gif and hiding them when various conditional statements or condition statements inside loops are fulfilled after or before certain duration of time.
    This is done inside void loop().

    To debug the problem I tried to run a simple code (which I have shown in the first post of this thread) only displaying a gif using the gifAnimation library. The same crash occurred. This meant that the library isn't working on android mode.

    And now I need a solution which needs least changes in the working code I have written. It would be great if you could explain me the solution in this context. ..

    Thanks a lot!! You are being a great help. :)

  • Did you run the code that I posted? You can position the webview in any location in your sketch and I believe you should be able to change the visibility dynamically.

    I will suggest to come up with a reduce version of your code where you implement your gif functionalities that you want and merging it with webview. Then test your code ensuring it run properly in android. I am not sure if webview is the solution to go as you will be loading several of them. It might work but I don't have much experience implementing several of them at once.

    You can always post in the forum if there are some alternate methods to display gif files in android mode.

    If you want your code to work in Android and the gif library doesn't work, then you have two options. Make your app only PC runnable OR you wil have to put some extra effort to make it work in android. That is, you might have to change your code to adapt it to new tools.

    If you implement a shorter version with the code I provided you, I could assist further. However I won't be able to work in your original code.

    Kf

  • edited July 2016 Answer ✓

    @SuysahN===

    looking to your code i understand that using gif is more complicated than i thought (webview class); of course you can dynamically hide or show a web view (which inherits View) but with this workaround you cannot show or hide this one or this other gif (on the same html); one solution could be to use the frames from your gifs, put them in an arrayList() then get them and put them in a simple view in a relativelayout: so you can start, pause, loop or stop the gif and you can set the view where you want...Another one, more elegant, could be to make your webwiew client from your html adding to that javaScript methods: start, stop and so on, then sending from processing calls to theses methods.Last one could be to create multiple html: first with this gif running looping, second one with 2 gifs running, third one with 2 stopped gifs etc, according to your code: after that you change the webwiew contents.

Sign In or Register to comment.