private ImageData writeImageAnimatedGif(OutputStream os) throws IOException {

    final LimitFinder limitFinder = new LimitFinder(TextBlockUtils.getDummyStringBounder(), true);
    udrawable.drawU(limitFinder);
    final Dimension2D dim =
        new Dimension2DDouble(
            limitFinder.getMaxX() + 1 + margin1 + margin2,
            limitFinder.getMaxY() + 1 + margin1 + margin2);

    final MinMax minmax = affineTransformations.getMinMax(dim);

    final AnimatedGifEncoder e = new AnimatedGifEncoder();
    // e.setQuality(1);
    e.setRepeat(0);
    e.start(os);
    // e.setDelay(1000); // 1 frame per sec
    // e.setDelay(100); // 10 frame per sec
    e.setDelay(60); // 16 frame per sec
    // e.setDelay(50); // 20 frame per sec

    for (AffineTransformation at : affineTransformations.getAll()) {
      final ImageIcon ii = new ImageIcon(getAviImage(at));
      e.addFrame((BufferedImage) ii.getImage());
    }
    e.finish();
    return new ImageDataSimple(dim);
  }
  private ImageData writeImageTOBEMOVED(
      FileFormatOption fileFormatOption, OutputStream os, Animation affineTransforms)
      throws IOException {
    final LimitFinder limitFinder = new LimitFinder(TextBlockUtils.getDummyStringBounder(), true);
    udrawable.drawU(limitFinder);
    Dimension2D dim =
        new Dimension2DDouble(
            limitFinder.getMaxX() + 1 + margin1 + margin2,
            limitFinder.getMaxY() + 1 + margin1 + margin2);
    double dx = 0;
    double dy = 0;
    if (affineTransforms != null) {
      final MinMax minmax = affineTransformations.getMinMax(dim);
      affineTransforms.setDimension(dim);
      dim = minmax.getDimension();
      dx = -minmax.getMinX();
      dy = -minmax.getMinY();
    }

    final UGraphic2 ug = createUGraphic(fileFormatOption, dim, affineTransforms, dx, dy);
    udrawable.drawU(handwritten(ug.apply(new UTranslate(margin1, margin1))));
    ug.flushUg();
    ug.writeImageTOBEMOVED(os, metadata, 96);
    os.flush();

    if (ug instanceof UGraphicG2d) {
      final Set<Url> urls = ((UGraphicG2d) ug).getAllUrlsEncountered();
      if (urls.size() > 0) {
        final CMapData cmap = CMapData.cmapString(urls, dpiFactor);
        return new ImageDataComplex(dim, cmap, warningOrError);
      }
    }

    return new ImageDataSimple(dim);
  }
  private Image getAviImage(AffineTransformation affineTransform) throws IOException {
    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
    writeImageTOBEMOVED(
        new FileFormatOption(FileFormat.PNG), baos, Animation.singleton(affineTransform));
    baos.close();

    final ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    final Image im = ImageIO.read(bais);
    bais.close();
    return im;
  }
  private UGraphic2 createUGraphicPNG(
      ColorMapper colorMapper,
      double dpiFactor,
      final Dimension2D dim,
      HtmlColor mybackcolor,
      Animation affineTransforms,
      double dx,
      double dy) {
    Color backColor = Color.WHITE;
    if (mybackcolor instanceof HtmlColorSimple) {
      backColor = colorMapper.getMappedColor(mybackcolor);
    } else if (mybackcolor instanceof HtmlColorTransparent) {
      backColor = null;
    }

    /*
     * if (rotation) { builder = new EmptyImageBuilder((int) (dim.getHeight() * dpiFactor), (int) (dim.getWidth() *
     * dpiFactor), backColor); graphics2D = builder.getGraphics2D(); graphics2D.rotate(-Math.PI / 2);
     * graphics2D.translate(-builder.getBufferedImage().getHeight(), 0); } else {
     */
    final EmptyImageBuilder builder =
        new EmptyImageBuilder(
            (int) (dim.getWidth() * dpiFactor), (int) (dim.getHeight() * dpiFactor), backColor);
    final Graphics2D graphics2D = builder.getGraphics2D();

    // }
    final UGraphicG2d ug =
        new UGraphicG2d(
            colorMapper,
            graphics2D,
            dpiFactor,
            affineTransforms == null ? null : affineTransforms.getFirst(),
            dx,
            dy);
    ug.setBufferedImage(builder.getBufferedImage());
    final BufferedImage im = ((UGraphicG2d) ug).getBufferedImage();
    if (mybackcolor instanceof HtmlColorGradient) {
      ug.apply(new UChangeBackColor(mybackcolor))
          .draw(new URectangle(im.getWidth(), im.getHeight()));
    }

    return ug;
  }