16 Replies Latest reply: May 17, 2012 3:29 AM by myoscaroxy RSS

    DisplacementMapFilter problem

    myoscaroxy Community Member

      Did somebody's worked by DisplacementMapFilter? It don't work fine on iPhone, while on flashplayer is correct. In particular, on iPhone, the filter create a image with pseudo-random pixel, without apparent logic, why?

       

      Maybe that filter isn't implemented?

       

      I would create an app that deforms an image through finger got from a picture done by camera, do exist an alternative method without DisplacementMapFilter?

       

      thanks

        • 1. Re: DisplacementMapFilter problem
          SirDragoon

          Do you use CPU or GPU render mode ? You should use CPU to apply filter.

           

          Here a small exemple to deforme a picture when you touch screen. (I test it on my Samsung Galaxy S)

           

          *Sorry for french comment...

           

          The "Img" class is a Bitmap (your picture)

          The "Vague" class is a MovieClip Animation of wave (black and white).

           

          Main Class:

           

          package
          {
              import flash.display.Bitmap;
              import flash.display.Sprite;
              import flash.display.StageAlign;
              import flash.display.StageScaleMode;
              import flash.events.AccelerometerEvent;
              import flash.events.Event;
              import flash.events.MouseEvent;
              import flash.events.TouchEvent;
              import flash.geom.Matrix;
              import flash.sensors.Accelerometer;
              import flash.text.TextField;
             
              import modules.fx.Deformation;
             
              import modules.utils.FPSCounter;
             
              /**
               * ...
               * @author Michaël Chartrand
               */
              public class Main extends Sprite {
                 
                  private var _img:Bitmap;
                  private var deformation:Deformation;
                 
                  public function Main():void {
                      //setup stage
                      stage.scaleMode = StageScaleMode.NO_SCALE;
                      stage.align = StageAlign.TOP_LEFT;

           

                      //add handlers
                      addEventListener(Event.ADDED_TO_STAGE, init);
                  }
                 
                  private function init(event:Event):void{
                          //removes listener
                          removeEventListener(Event.ADDED_TO_STAGE, init);
                         
                          _img = new Bitmap(new Img);
                          addChild(_img);

           

                          setupTransformBitmap();
                  }
                 
                  private function setupTransformBitmap():void{
                      deformation = new Deformation(_img);
                      this.addEventListener(Event.ENTER_FRAME, rappel);
                      this.stage.addEventListener(MouseEvent.CLICK, ajoute);
                     
                      var fps:FPSCounter = new FPSCounter(0, 0);
                      addChild(fps);
                  }
                 
                  //FONCTION rappel
                  //--------------------------------------------------------
                  private function rappel(event:Event):void{
                      deformation.appliqueEffet();
                  }
                 
                  //FONCTION ajoute
                  //--------------------------------------------------------
                  private function ajoute(event:MouseEvent):void {
                      deformation.ajouteEffet(Vague, mouseX, mouseY);
                  }

           

              }
             
          }

           

           

           

           

          Deformation Class:

           

          package modules.fx{

           

              /**
               * ...
               * @author Michaël Chartrand.
               */

           

              //IMPORTATIONS
              //--------------------------------------------------------
              import flash.display.MovieClip;
              import flash.display.DisplayObject;
              import flash.display.Bitmap;
              import flash.display.BitmapData;
              import flash.filters.DisplacementMapFilter;
              import flash.filters.DisplacementMapFilterMode;
              import flash.geom.Point;
              import modules.forme.Rectangle;

           

              //CLASS Deformation
              //--------------------------------------------------------
              public class Deformation extends MovieClip {

           

                  //PROPRIÉTÉS
                  //--------------------------------------------------------
                  private var _imageBitmap:BitmapData;
                  private var _displacementMap:DisplacementMapFilter;
                  private var _contenant:MovieClip;
                  private var _rectangle:Rectangle;
                 
                  private var _objet:DisplayObject;
                 
                  //FONCTION Deformation
                  //--------------------------------------------------------
                  public function Deformation(objet:DisplayObject) {
                      //Affectation
                      _objet = objet;
                     
                      //Création d'un bitmap d'après les proportion d'une image.
                      _imageBitmap = new BitmapData(_objet.width, _objet.height, false, 0x000000);
                     
                      //Contenant de l'effets et du rectangle
                      _contenant = new MovieClip();
                      _contenant.x = _objet.x;
                      _contenant.y = _objet.y;
                      _contenant.visible = false;
                     
                      addChild(_contenant);
                     
                      //Forme un Rectangle
                      //--------------------------------------------------------
                     
                      //Arguments    :: couleurFond, transparenceFond, couleurContour, pixelContour, transparenceContour, largeur, hauteur, coinLargeur, coinHauteur
                      _rectangle = new Rectangle(0x000000, 1, 0x000000, 0, 1, _objet.width, _objet.height, 0, 0);
                      _rectangle.x = _objet.x;
                      _rectangle.y = _objet.y;
                      _contenant.addChild(_rectangle);
                  }
                 
                  //FONCTION ajouteEffet
                  //--------------------------------------------------------
                  public function ajouteEffet(classe:Class, posX:int, posY:int):void{
                      var effet:MovieClip = new classe;
                      effet.x = posX;
                      effet.y = posY;
                      _contenant.addChild(effet);
                  }
                 
                  //FONCTION appliqueEffet
                  //--------------------------------------------------------
                  public function appliqueEffet():void{
                      //Reproduit l'image sur le bitmap
                      _imageBitmap.draw(_contenant);
                     
                      //Crée le filtre de déformatiom
                      _displacementMap = new DisplacementMapFilter(_imageBitmap, new Point(0, 0), 1, 1, 10, 10, DisplacementMapFilterMode.CLAMP);
                 
                      //Applique le filtre de déformation
                      _objet.filters = [_displacementMap];
                  }
                 
              }
          }

          • 2. Re: DisplacementMapFilter problem
            myoscaroxy Community Member

            I will try on iPhone, for now thanks a lot

             

            dès

            • 3. Re: DisplacementMapFilter problem
              myoscaroxy Community Member

              I tried on iPhone setted "CPU" in tag xml, but nothing, the filter don't work fine.

               

              When I run app in Flash CS5 publish, it work fine, but when I put ipa file into iPhone the filter don't work, in fact it draw the circle concentric that don't reflect my setting on the map.

               

              although the source is very simple (the ImgCls() is a BitmapData that represents the image from to deform):

               

               

              package{

              import flash.display.Bitmap;

              import flash.display.BitmapData;

              import flash.display.BitmapDataChannel;

              import flash.display.BlendMode;

              import flash.display.GradientType;

              import flash.display.InterpolationMethod;

              import flash.display.MovieClip;

              import flash.display.SpreadMethod;

              import flash.display.Sprite;

              import flash.display.StageAlign;

              import flash.display.StageScaleMode;

              import flash.events.Event;

              import flash.events.MouseEvent;

              import flash.filters.DisplacementMapFilter;

              import flash.filters.DisplacementMapFilterMode;

              import flash.geom.Matrix;

              import flash.geom.Point;

              import flash.text.TextField;

              import flash.text.TextFormat;

              import flash.desktop.NativeApplication;

              import flash.desktop.SystemIdleMode;

               

              /* import flash.display.StageAlign;

                  import flash.display.StageScaleMode;

                  import flash.desktop.NativeApplication;

                  import flash.desktop.SystemIdleMode;  */

               

              public class Main extends MovieClip {

               

              private var previous:Point;

              private var sprite:Sprite;

              private var mouseDown:Boolean;

              private var map:BitmapData;

               

              private var softness:Array = [0,255];

              private var size:uint = 60;

              private var sizeMezzi:int = 30

              private var hardness:uint = 2;

               

              private var txtField:TextField;

               

              private var imgBitmap:Bitmap;

              private var ui:Sprite;

              private var zero:Point = new Point();

               

              public function Main(){

              super();

              addEventListener(Event.ADDED, init);

              }

               

              private function init(e:Event):void{

              var tf:TextFormat = new TextFormat();

               

              removeEventListener(Event.ADDED, init);

              stage.align = StageAlign.TOP_LEFT;

              stage.scaleMode = StageScaleMode.NO_SCALE;

              NativeApplication.nativeApplication.systemIdleMode = SystemIdleMode.KEEP_AWAKE;

               

              sprite = new Sprite();

              ui = new Sprite();

              txtField = new TextField();

              txtField.width = 320;

              txtField.height = 480;

              tf.color = 0xffffff;

              tf.font = "arial";

              txtField.defaultTextFormat = tf;

               

              txtField.wordWrap = true;

              ui.graphics.beginFill(0x00ff00,0);

              ui.graphics.drawRect(0,0,320,480);

               

              imgBitmap = new Bitmap(new ImgCls());

              addChild(imgBitmap);

              addChild(txtField);

              addChild(ui);

               

              drawSprite();

               

              sprite.blendMode = BlendMode.INVERT;

               

               

              this.addEventListener( Event.ENTER_FRAME, onEnterFrame );

              ui.addEventListener( MouseEvent.MOUSE_DOWN, handleMouseDown );

              ui.addEventListener( MouseEvent.MOUSE_UP, handleMouseUp );

               

               

              }

               

              private function drawSprite( ):void {

              var matrix:Matrix = new Matrix( );

               

              matrix.createGradientBox( size, size, 0 );

              sprite.graphics.clear();

              sprite.graphics.beginGradientFill( GradientType.RADIAL, [0xFF0000, 0x000000], [1, 0], softness, matrix, SpreadMethod.PAD, InterpolationMethod.LINEAR_RGB);

              sprite.graphics.drawCircle( size/2, size/2, size/2 );

              sprite.graphics.endFill();

               

              createMap();

              }

               

              private function createMap( ):void{

              map = new BitmapData( size, size, false, 128 << 16 || 128 << 8 || 128);

              map.draw( sprite, new Matrix(1, 0, 0, 1, 0, 0), null, BlendMode.HARDLIGHT );

              }

               

              private function drawDisplacement( bmp:BitmapData, current:Point ):void {

               

              var displFilter:DisplacementMapFilter = new DisplacementMapFilter(

              bmp,

              current,

              BitmapDataChannel.RED,

              BitmapDataChannel.RED,

              ( previous.x - current.x )*hardness,

              ( previous.y - current.y )*hardness,

              DisplacementMapFilterMode.WRAP

              );

              imgBitmap.bitmapData.applyFilter( imgBitmap.bitmapData, imgBitmap.bitmapData.rect, zero, displFilter );

              //txtField.appendText("ok ");

              }

               

              private function onEnterFrame( event:Event ):void{

              var current:Point = new Point( stage.mouseX - sprite.width/2, stage.mouseY - sprite.height/2 );

              sprite.x = current.x;

              sprite.y = current.y;

              if( mouseDown && (current.x != previous.x || current.y != previous.y))

              drawDisplacement( map, current );

               

              previous = current.clone();

              }

               

              private function handleMouseDown( event:MouseEvent ):void{

              mouseDown = true;

              }

               

              private function handleMouseUp( event:MouseEvent ):void {

              mouseDown = false;

              }

               

              }

              }

               

               

              p.s. I would to try your example but you would have to give me the "modules.forme.Rectangle" class, thanks

              • 4. Re: DisplacementMapFilter problem
                ogilquin Community Member

                I have the same problem, I tried also Pixel Bender on CPU and GPU but the image isn't filtered.

                 

                Does anybody know if filtering will be possible with AIR 2.7 for iOS ?

                • 5. Re: DisplacementMapFilter problem
                  myoscaroxy Community Member

                  After 3 months no reply ... why?

                  • 6. Re: DisplacementMapFilter problem
                    sanika Kulshreshtha Adobe Employee

                    Hi,

                    @myoscaroxy I tried your code and I am not able to see any difference in output on desktop and iOS. Could you please attach a screenshot, or file a bug at http://bugbase.adobe.com with an example?

                     

                    Thanks,

                    Sanika

                    • 8. Re: DisplacementMapFilter problem
                      sanika Kulshreshtha Adobe Employee

                      Thanks for the screenshot. I am able to reproduce the bug. It is currently under investigation.

                       

                      Regards,

                      Sanika

                      • 9. Re: DisplacementMapFilter problem
                        myoscaroxy Community Member

                        if you give me your email I sent you my complete project (it's easy app) so you can to accelerate the work.

                         

                        thanks

                        • 10. Re: DisplacementMapFilter problem
                          sanika Kulshreshtha Adobe Employee

                          You could report the bug yourself at http://bugbase.adobe.com along with the app sources. The bug will be visible publicly, so you will come of any updates on the bug.

                           

                          Thanks.

                          Sanika

                          • 12. Re: DisplacementMapFilter problem
                            cnuuja Adobe Employee

                            Looks like perhaps an authoring error?  Its not the filter that's the problem, its the inputs to the filter.   the code is using stage.mouseX / stage.mouseY to see where to apply the filter; and also previous.x/y - current.x/y to see how much to apply.

                             

                            On desktop, stage.mouseX/Y are updated per pixcel changes while mouse is moving. But on mobile, with touch input, they don't. So what happens on mobile is that previous.xy - current.xy could be a large value if the two touches are far way on screen. So that leads to a large filter to apply.

                             

                            So I think this is a UserError one.

                             

                            On mobile:

                             

                            mouseDown----------------------------------------------

                            previous=221,186 & current=149,311

                            mouseDown=true

                            drawDisplacement!!!!!!!

                            previous=221,186 & current 221,186

                            mouseDown=true

                            mouseUp----------------------------------------------

                            • 13. Re: DisplacementMapFilter problem
                              myoscaroxy Community Member

                              YOU HAVE RIGHT!

                               

                              the displacement work fine (both  2.6 and 2.7), in my app the value that I put into the filter is left.

                               

                              thaks a lot, you are a genius

                              • 14. Re: DisplacementMapFilter problem
                                phpsaux

                                myoscaroxy, do you can help me, showing your code with solution? I've the same problem. I see that problem is the x,y of Touch position, but I could not to solve this.  Thanks!!!

                                • 15. Re: DisplacementMapFilter problem
                                  myoscaroxy Community Member

                                  it's all:

                                   

                                  private function drawSprite():void{

                                  var matrix:Matrix = new Matrix( );






                                  _size = _sizeOriginale * _scaleSprite;

                                  _sizeMezzi = _size / 2;

                                  matrix.createGradientBox( _size, _size, 0 );

                                  sprite.graphics.clear();

                                  sprite.graphics.beginGradientFill( GradientType.RADIAL, [0xFF0000, 0x000000], [1, 0], softness, matrix, SpreadMethod.PAD, InterpolationMethod.LINEAR_RGB);

                                  sprite.graphics.drawCircle( _sizeMezzi, _sizeMezzi, _sizeMezzi );

                                  sprite.graphics.endFill();

                                  createMap();

                                  }

                                   

                                   

                                  private function createMap( ):void{


                                  map = new BitmapData( _size, _size, false, 128 << 16 || 128 << 8 || 128);

                                  map.draw( sprite, new Matrix(1, 0, 0, 1, 0, 0), null, BlendMode.HARDLIGHT );

                                  }

                                   

                                   

                                  private function drawDisplacement( bmp:BitmapData, currentX:int, currentY:int ):void{

                                  _point.x = currentX;

                                  _point.y = currentY;

                                  _displFilter = new DisplacementMapFilter(




                                  bmp,




                                  _point,




                                  BitmapDataChannel.RED,




                                  BitmapDataChannel.RED,




                                  ( _previousX - currentX )*hardness,




                                  ( _previousY - currentY )*hardness,




                                  DisplacementMapFilterMode.CLAMP




                                  );


                                  imgBitmap.bitmapData.applyFilter( imgBitmap.bitmapData, imgBitmap.bitmapData.rect, _zero, _displFilter );

                                  }

                                   

                                   

                                  private function onTouchMove( event:Event ):void{


                                  if (event as MouseEvent){


                                  _currentX = MouseEvent(event).stageX  - (sprite.width * _scaleFactor)/2 ;


                                  _currentY = MouseEvent(event).stageY  - (sprite.height* _scaleFactor)/2;

                                  }else{


                                  _currentX = TouchEvent(event).stageX - sprite.width/2;


                                  _currentY = TouchEvent(event).stageY - sprite.height/2;

                                  }

                                  _currentX = imgBitmap.globalToLocal(new Point(_currentX,_currentY)).x ;

                                  _currentY = imgBitmap.globalToLocal(new Point(_currentX,_currentY)).y ;



                                  sprite.x = _currentX;

                                  sprite.y = _currentY;

                                  if (_startBeginTouch){


                                  _previousX = _currentX;


                                  _previousY = _currentY;


                                  _startBeginTouch = false;

                                  }

                                  if( _mouseDown && (_currentX != _previousX || _currentY != _previousY)){


                                  drawDisplacement( map, _currentX, _currentY);

                                  }



                                  _previousX = _currentX;

                                  _previousY = _currentY;

                                  }

                                   

                                   

                                  private function onTouchBegin(e:Event):void{


                                  _mouseDown = true;

                                  _startBeginTouch = true;

                                  }

                                   

                                   

                                  private function onTouchEnd(e:Event):void{


                                  _mouseDown = false;

                                  }

                                  • 16. Re: DisplacementMapFilter problem
                                    myoscaroxy Community Member

                                    I alarmed you that I tried to work with big image, or better, image from camera and the app becomes very slow. I tried to create an app for the image distortion but the result is wrong, what a pity!

                                     

                                    I tried with air 3.2 on 3gs iPhone.