Uploaded image for project: 'Batik'
  1. Batik
  2. BATIK-1361

Animated rotate() tranform ignores y-origin at exactly 270 degrees

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 1.17
    • 1.18
    • None
    • None
    • Batik 1.17; Java 17; Windows 10

    Description

      I have a small (3 sec) SVG animation I'm tryng to render the individual frames of as bitmaps, like:

      import java.nio.file.Path;
      
      import org.w3c.dom.Document;
      
      import org.apache.batik.transcoder.SVGAbstractTranscoder;
      import org.apache.batik.transcoder.TranscoderInput;
      import org.apache.batik.transcoder.TranscoderOutput;
      import org.apache.batik.transcoder.image.ImageTranscoder;
      import org.apache.batik.transcoder.image.PNGTranscoder;
      
              Path framesDir;
              Document svgDoc;
              ...
      
              TranscoderInput svg = new TranscoderInput(svgDoc);
      
              final float duration = 3.0f;
              final float frameRate = 20;
      
              ImageTranscoder transcoder = new PNGTranscoder();
              transcoder.addTranscodingHint(
                      SVGAbstractTranscoder.KEY_EXECUTE_ONLOAD, true);
      
              float animTime = 0;
              for (int frame = 1; animTime < duration; animTime = frame++ / frameRate) {
                  transcoder.addTranscodingHint(
                          SVGAbstractTranscoder.KEY_SNAPSHOT_TIME, animTime);
      
                  Path frameFile = framesDir.resolve(BASE_NAME + "-" + frame + ".png");
                  try (OutputStream fout = Files.newOutputStream(frameFile)) {
                      transcoder.transcode(svg, new TranscoderOutput(fout));
                  }
              }
      

      I'm noticing with this specific animation (wait.svg) one of the frames is "broken":

      Frame #46

      This appears when I'm rendering 20 fps for a total of 60 frames (3 seconds). I've tried 15 fps and 30 fps, and I'm not observing such broken frames. Then I've tried 40 fps and I'm seeing few more broken frames:

      Frame #46 Frame #91 Frame #106

      At 45 and 50 fps I'm not observing broken frames. At 60 fps I'm observing one broken frame:

      Frame #136

      I'm noticing some magic numbers here:

      46 (1-based) = 45 (0-based)
      91 - 46 = 45
      136 - 91 = 45
      

      Not sure how and if #106 fits in here... but 136 - 106 = 20 - the common 20, 40, 60 (fps) denominator 🤪.

      Steps to Reproduce

      1. Save wait.svg and SVGAnimTest.java into a single directory;
      2. From the same directory execute:
        java -cp <batik-dist>/lib/* SVGAnimTest.java
        
      3. Observe the animation frames in the output wait-20fps directory.

      Actual Results

      Frame wait-20fps-046.png is broken.

      Expected Results

      All frames should be fine.

      Details

      To experiment with different frame rates use:

      java -cp <batik-dist>/lib/* SVGAnimTest.java [fps]
      

      f.e.:

      java -cp <batik-dist>/lib/* SVGAnimTest.java 40
      

      Disclaimer: The original wait.svg is from the Bibata_Cursor project.

      Attachments

        1. DebugSVGAnimation.java
          4 kB
          Stanimir Stamenkov
        2. frame-1.4750.png
          3 kB
          Stanimir Stamenkov
        3. frame-1.5000.png
          0.8 kB
          Stanimir Stamenkov
        4. frame-1.5000@.png
          0.8 kB
          Stanimir Stamenkov
        5. frame-1.5250.png
          3 kB
          Stanimir Stamenkov
        6. left_ptr_watch.svg
          4 kB
          Stanimir Stamenkov
        7. left_ptr_watch-20fps-046.png
          4 kB
          Stanimir Stamenkov
        8. rotate-center-0.svg
          0.4 kB
          Stanimir Stamenkov
        9. rotate-center-1.svg
          0.4 kB
          Stanimir Stamenkov
        10. rotate-center-2.svg
          0.4 kB
          Stanimir Stamenkov
        11. rotate-origin.svg
          0.9 kB
          Stanimir Stamenkov
        12. rotate-origin2.svg
          0.9 kB
          Stanimir Stamenkov
        13. SVGAnimTest.java
          4 kB
          Stanimir Stamenkov
        14. SVGAnimTest2.java
          5 kB
          Stanimir Stamenkov
        15. SVGAnimTest3.java
          4 kB
          Stanimir Stamenkov
        16. wait.svg
          2 kB
          Stanimir Stamenkov
        17. wait-0.5375.png
          7 kB
          Stanimir Stamenkov
        18. wait-0.5625@.png
          6 kB
          Stanimir Stamenkov
        19. wait-0.5875.png
          7 kB
          Stanimir Stamenkov
        20. wait-1.1000.png
          7 kB
          Stanimir Stamenkov
        21. wait-1.1250@.png
          6 kB
          Stanimir Stamenkov
        22. wait-1.1500.png
          7 kB
          Stanimir Stamenkov
        23. wait-1.7250.png
          7 kB
          Stanimir Stamenkov
        24. wait-1.7500@.png
          7 kB
          Stanimir Stamenkov
        25. wait-1.7750.png
          7 kB
          Stanimir Stamenkov
        26. wait-2.2250.png
          6 kB
          Stanimir Stamenkov
        27. wait-2.2500@.png
          6 kB
          Stanimir Stamenkov
        28. wait-2.2750.png
          6 kB
          Stanimir Stamenkov
        29. wait-20fps-046.png
          4 kB
          Stanimir Stamenkov
        30. wait-40fps-046.png
          4 kB
          Stanimir Stamenkov
        31. wait-40fps-091.png
          4 kB
          Stanimir Stamenkov
        32. wait-40fps-106.png
          4 kB
          Stanimir Stamenkov
        33. wait-60fps-136.png
          4 kB
          Stanimir Stamenkov

        Issue Links

          Activity

            People

              ssteiner Simon Steiner
              stanio Stanimir Stamenkov
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: