Copy link to clipboard
Copied
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
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
...Copy link to clipboard
Copied
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];
}
}
}
Copy link to clipboard
Copied
I will try on iPhone, for now thanks a lot
dès
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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 ?
Copy link to clipboard
Copied
After 3 months no reply ... why?
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Thanks for the screenshot. I am able to reproduce the bug. It is currently under investigation.
Regards,
Sanika
Copy link to clipboard
Copied
if you give me your email I sent you my complete project (it's easy app) so you can to accelerate the work.
thanks
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
Copy link to clipboard
Copied
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----------------------------------------------
Copy link to clipboard
Copied
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
Copy link to clipboard
Copied
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!!!
Copy link to clipboard
Copied
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; |
}
Copy link to clipboard
Copied
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.