first version of GIF write support
Stefan Schuermans

Stefan Schuermans commited on 2018-09-18 20:41:57
Showing 1 changed files, with 79 additions and 0 deletions.

... ...
@@ -1418,6 +1418,83 @@ public class BlinkenMovie
1418 1418
     return false;
1419 1419
   }
1420 1420
 
1421
+  public boolean saveGif( String filename )
1422
+  {
1423
+    try {
1424
+
1425
+      //create GIF writer
1426
+      ImageWriter gifWr = null;
1427
+      {
1428
+        Iterator<ImageWriter> it = ImageIO.getImageWritersBySuffix( "gif" );
1429
+        if ( ! it.hasNext( ) ) {
1430
+          return false;
1431
+        }
1432
+        gifWr = it.next();
1433
+      }
1434
+
1435
+      //begin writing image
1436
+      ImageOutputStream out = new FileImageOutputStream( new File( filename ) );
1437
+      gifWr.setOutput( out );
1438
+      gifWr.prepareWriteSequence( null );
1439
+
1440
+      //create buffered image with correct dimensions
1441
+      BufferedImage img = new BufferedImage( this.width, this.height,
1442
+                                             BufferedImage.TYPE_INT_ARGB );
1443
+
1444
+      //process all frames
1445
+      int cnt = this.getFrameCnt( );
1446
+      for( int i = 0; i < cnt; i++ )
1447
+      {
1448
+
1449
+        //frame data into buffered image
1450
+        for( int y = 0; y < this.height; y++ )
1451
+          for( int x = 0; x < this.width; x++ )
1452
+            img.setRGB( x, y, this.frames[i].getColor( y, x ).getRGB( ) );
1453
+
1454
+        //get frame duration
1455
+        int duration = this.frames[i].getDuration( );
1456
+
1457
+        //construct metadata
1458
+        ImageWriteParam prm = gifWr.getDefaultWriteParam( );
1459
+        ImageTypeSpecifier typeSpec = ImageTypeSpecifier.createFromBufferedImageType( img.getType( ) );
1460
+        IIOMetadata meta = gifWr.getDefaultImageMetadata( typeSpec, prm );
1461
+        String metaFmt = meta.getNativeMetadataFormatName( );
1462
+        IIOMetadataNode metaRoot = (IIOMetadataNode)meta.getAsTree( metaFmt );
1463
+        String nameGCE = "GraphicControlExtension";
1464
+        IIOMetadataNode metaGCE = null;
1465
+        for( int n = 0; n < metaRoot.getLength(); n++ ) {
1466
+          Node node = metaRoot.item(n);
1467
+          if( node.getNodeName().compareToIgnoreCase(nameGCE) == 0 ) {
1468
+            metaGCE = (IIOMetadataNode)node;
1469
+          }
1470
+        }
1471
+        if( metaGCE == null ) {
1472
+          metaGCE = new IIOMetadataNode( nameGCE );
1473
+          metaRoot.appendChild( metaGCE );
1474
+        }
1475
+        metaGCE.setAttribute( "disposalMethod", "doNotDispose" );
1476
+        metaGCE.setAttribute( "transparentColorFlag", "FALSE" );
1477
+        metaGCE.setAttribute( "transparentColorIndex", "0" );
1478
+        metaGCE.setAttribute( "delayTime", Integer.toString( (duration + 5) / 10 ) );
1479
+        metaGCE.setAttribute( "userInputFlag", "FALSE" );
1480
+        meta.setFromTree( metaFmt, metaRoot );
1481
+
1482
+        //write image
1483
+        gifWr.writeToSequence( new IIOImage( img, null, meta ), prm );
1484
+
1485
+      }
1486
+
1487
+      //finalize image
1488
+      gifWr.endWriteSequence( );
1489
+      out.close( );
1490
+
1491
+      return true;
1492
+    }
1493
+    catch( IOException e ) { }
1494
+
1495
+    return false;
1496
+  }
1497
+
1421 1498
   public boolean save( String filename )
1422 1499
   {
1423 1500
     if( filename.endsWith( ".blm" ) )
... ...
@@ -1428,6 +1505,8 @@ public class BlinkenMovie
1428 1505
       return saveBml( filename );
1429 1506
     if( filename.endsWith( ".bbm" ) )
1430 1507
       return saveBbm( filename );
1508
+    if( filename.endsWith( ".gif" ) )
1509
+      return saveGif( filename );
1431 1510
     return false;
1432 1511
   }
1433 1512
 
1434 1513