6 Replies Latest reply on Nov 18, 2008 2:28 AM by kiwi_ziesch

    Create thumbnail from selected images

    kiwi_ziesch Level 1
      Hi,
      in my app the user can choose some pictures from his local file system.
      I want to create a smaller image of every selected picture.
      So I do this for each image:

      for( var f = 0; f < e.files.length; f++ ){
      name = e.files[f].name;
      src = e.files[f].url;
      path = e.files[f].parent.url;

      files.push( e.files[f] );
      //...some other code, not important for this...//

      image = new air.Loader();
      image.contentLoaderInfo.addEventListener( air.Event.COMPLETE, function() {
      var ratio = null;
      if (image.width <= 100) {
      thumb_height = image.height;
      thumb_width = image.width;
      ratio = 1;
      }
      else {
      var thumb_width = 100;
      var thumb_height = null;
      var factor = image.width / thumb_width;
      thumb_height = Math.round(image.height / factor);
      ratio = 100/ image.width;
      if (thumb_height > thumb_width) {
      thumb_height = 120;
      factor = image.height / thumb_height;
      thumb_width = Math.round(image.width / factor);
      }
      ratio = 100/ image.width;
      }

      var bmp = new air.BitmapData( thumb_width, thumb_height );
      var temp = air.File.createTempFile();
      var desktop = null;
      var matrix = new air.Matrix();
      var png = null;
      var stream = new air.FileStream();
      var div = null;
      var elem = null;

      matrix.scale( ratio,ratio );
      bmp.draw( image.content, matrix );

      png = runtime.com.adobe.images.PNGEncoder.encode( bmp );

      stream.open( temp, air.FileMode.WRITE );
      stream.writeBytes( png, 0, 0 );
      stream.close();

      desktop = air.File.desktopDirectory.resolvePath( toPNG( e.files[f] ) );
      temp.moveTo( desktop, true );
      } );

      image.load( new air.URLRequest(e.files[f] ) );
      }

      function toPNG( orig )
      {
      return orig.name.substr( 0, orig.name.length - orig.extension.length ) + 'png';
      }

      The problem is, that the "thumbnail" is only created of the last selected image. I think it has something to do with the air.Event.COMPLETE event. But when I kick that off, an error occures: Error #2015: Invalid BitmapData. at flash.display::BitmapData().

      Hope somebody can help. Thanks in advance
        • 1. Re: Create thumbnail from selected images
          kiwi_ziesch Level 1
          sorry, that wasn´t the solution...the thumbs are created but have all the same content - the last pic.
          i´m working on this code since hours :(

          please help me out. thanks very much!
          • 2. Re: Create thumbnail from selected images
            kiwi_ziesch Level 1
            it seems like the source of Loader is overwritten and that´s why all created images have the same content, width and height. how do I create a specific loader for every pic?

            current code is:

            var k = 0;

            function doSelect( e ) {

            files = new Array();

            for( var f = 0; f < e.files.length; f++ ){
            src = e.files[f].url;
            files.push( e.files[f] );

            image = new air.Loader();
            image.contentLoaderInfo.addEventListener( air.Event.COMPLETE, doComplete );

            image.load( new air.URLRequest( src ) );

            }
            }

            function doComplete() {
            //resizing factors
            var ratio = null;
            if (image.width <= 100) {
            thumb_height = image.height;
            thumb_width = image.width;
            ratio = 1;
            }
            else {
            var thumb_width = 100;
            var thumb_height = null;

            var factor = image.width / thumb_width;

            thumb_height = Math.round(image.height / factor);

            ratio = 100 / image.width;

            if (thumb_height > thumb_width) {
            thumb_height = 120;
            factor = image.height / thumb_height;
            thumb_width = Math.round(image.width / factor);
            }
            ratio = 100 / image.width;
            }

            //create
            var bmp = new air.BitmapData(thumb_width, thumb_height);
            var temp = air.File.createTempFile();
            var desktop = null;
            var matrix = new air.Matrix();
            var png = null;
            var stream = new air.FileStream();
            var div = null;
            var elem = null;

            matrix.scale(ratio, ratio);
            bmp.draw( image.content, matrix );

            png = runtime.com.adobe.images.PNGEncoder.encode( bmp );

            stream.open( temp, air.FileMode.WRITE );
            stream.writeBytes( png, 0, 0 );
            stream.close();

            desktop = air.File.desktopDirectory.resolvePath('thumbs' + air.File.separator + toPNG( files[k] ) );
            temp.moveTo( desktop, true );
            k++;
            }

            function toPNG( orig )
            {
            return orig.name.substr( 0, orig.name.length - orig.extension.length ) + 'png';
            }

            I´ve traced the variable k, the name of the pic and it´s width in doComplete() and the result was:
            k is ok with 0,1,2 for 3 pics. the name of each pic is also ok but image.width is always the same. that means there´s something wrong with the loader. may it be that the eventlistener is not the right one?
            • 3. Re: Create thumbnail from selected images
              Hi kiwi_ziesch,

              I think this problem occurs because the Loader objects that you create are running almost at the same time since you are creating them using a for statement.
              Instead of using a for statement to create your Loader objects you should use a stack pattern : you create a first Loader object,load it with the first file and when your doComplete function is over you then create a new Loader object, load it with the second file, etc ...
              • 4. Create thumbnail from selected images
                kiwi_ziesch Level 1
                yes, of course - it must be something like that.
                I´m testing this at the moment but where should I create the new Loader. I´m doing this already in the doSelect()-function. Can you give me a short sample?
                I´m testing around since 8am and now it´s 8pm...
                Maybe I don´t see the wood for the trees ;)
                • 5. Re: Create thumbnail from selected images
                  kiwi_ziesch Level 1
                  Oliver C could you please give me an example of using a stack pattern to create the Loader object. I haven´t solved this problem yet.
                  I need the for statement to get the information about the selected file. When I go out of the for statement I don´t have the reference to the path of the image of what I want to create the thumbnail.
                  Thanks for any help.
                  • 6. Re: Create thumbnail from selected images
                    kiwi_ziesch Level 1
                    Here´s a nice example that does exactly what I want:

                    <html>
                    <head>

                    <title>Thumbnails</title>

                    <script src="library.swf" type="application/x-shockwave-flash"></script>
                    <script src="AIRAliases.js" type="text/javascript"></script>

                    <script type="text/javascript">
                    var MAX_HEIGHT = 100;
                    var MAX_WIDTH = 100;

                    var files = null;
                    var index = 0;
                    var loader = null;
                    var output = null;

                    function loadImages()
                    {
                    if( index < files.length )
                    {
                    output = document.createElement( 'div' );
                    loader.load( new air.URLRequest( files[index].url ) );
                    } else {
                    loader.visible = false;
                    }
                    }

                    function doLoad()
                    {
                    loader = new air.Loader();
                    loader.contentLoaderInfo.addEventListener( air.Event.COMPLETE, doLoaderComplete );
                    window.nativeWindow.stage.addChild( loader );

                    btnOpen.addEventListener( 'click', doOpenClick );
                    }

                    function doFilesSelect( e )
                    {
                    files = e.files;
                    index = 0;

                    loadImages();
                    }

                    function doLoaderComplete()
                    {
                    var bmpd = null;
                    var encoder = null;
                    var img = null;
                    var jpg = null;
                    var matrix = null;
                    var ratio = 0;
                    var realHeight = loader.contentLoaderInfo.height;
                    var realWidth = loader.contentLoaderInfo.width;
                    var stream = null;
                    var thumb = null;
                    var thumbHeight = 0;
                    var thumbWidth = 0;

                    if( realWidth > 0 )
                    {
                    if( realWidth <= MAX_WIDTH )
                    {
                    thumbHeight = realHeight;
                    thumbWidth = realWidth;
                    ratio = 1;
                    } else {
                    thumbWidth = MAX_WIDTH;
                    thumbHeight = 0;

                    factor = realWidth / thumbWidth;

                    thumbHeight = Math.round( realHeight / factor );

                    ratio = MAX_WIDTH / realWidth;

                    if( thumbHeight > thumbWidth )
                    {
                    thumbHeight = MAX_HEIGHT;
                    factor = realHeight / thumbHeight;
                    thumbWidth = Math.round( realWidth / factor );
                    }

                    ratio = MAX_WIDTH / realWidth;
                    }

                    matrix = new air.Matrix();
                    matrix.scale( ratio, ratio );

                    bmpd = new air.BitmapData( thumbWidth, thumbHeight );
                    bmpd.draw( loader, matrix );

                    encoder = new runtime.com.adobe.images.JPGEncoder( 85 );
                    jpg = encoder.encode( bmpd );

                    thumb = air.File.desktopDirectory.resolvePath( 'thumb_' + files[index].name );

                    stream = new air.FileStream();
                    stream.open( thumb, air.FileMode.WRITE );
                    stream.writeBytes( jpg, 0, 0 );
                    stream.close();

                    output.innerHTML = files[index].name + ': ' + realWidth + ' x ' + realHeight;
                    document.body.appendChild( output );

                    img = document.createElement( 'img' );
                    img.src = thumb.url;
                    output.appendChild( img );

                    index = index + 1;
                    loadImages();
                    }
                    }

                    function doOpenClick()
                    {
                    var browse = air.File.desktopDirectory;

                    browse.addEventListener( air.FileListEvent.SELECT_MULTIPLE, doFilesSelect );
                    browse.browseForOpenMultiple(
                    'Select Images',
                    [new air.FileFilter( 'Image Files', '*.gif;*.jpg;*.jpeg;*.png' )]
                    );
                    }
                    </script>

                    </head>
                    <body onLoad="doLoad();">

                    <input id="btnOpen" type="button" value="Open..." />

                    </body>
                    </html>