FLEX: After resizing Image, imageRotate doesn't work ordinarily - apache-flex

Please help me ㅠㅠ
I'm making ImageEditor. but I have a question for Image Rotating function.
When I load image and then Rotate it, Rotate function work very well.
But After resizing(width, height) loaded Image, rotate work ridiculously...
Pixed Image's width, height, It rotate only Image's content..
As a result, Quality of image go down...
This is screenshots.
Oh.. I can't post Images.. because reputation limit... :-<
http://blog.naver.com/hago89n/150164439917
Please visit my blog and confirm screenshots..
Can you understand my problem?
Um.. code is here
//resize button click handler
private function btn_resize_clickHandler(event:MouseEvent):void
{
image.width = parseInt(ti_width.text.toString());
image.height = parseInt(ti_height.text.toString());
}
//Rotate button click handler
private function btn_rotateCCW_clickHandler(event:MouseEvent):void
{//Rotate Counter ClockWise
var o_rotateimage:RotateImage = new RotateImage();
o_rotateimage.rotateCCW(image);
}
//Rotate function in RotateImage.as
public function rotateCCW(image:Image):void
{
m = new Matrix();
m.rotate(Math.PI/2);
m.tx = image.height;
var bd:BitmapData = new BitmapData(image.height as int, image.width as int);
bd.draw(image, m);
image.source = new Bitmap(bd);
}

I think you should do a matrix transformation for both operations.
If you just change the size of your Image object, it does not work fine in all situations.
Here is my code for this example.
//Application
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="955" minHeight="600">
<fx:Script>
<![CDATA[
import com.imageeditor.RotateImage;
[Embed(source="/assets/img/chart.png")]
[Bindable]
public var chartPng:Class;
private var o_rotateimage:RotateImage = new RotateImage();
private function btn_resize_clickHandler(event:MouseEvent):void
{
o_rotateimage.scale(image, int(ti_width.text)/image.width, int(ti_height.text)/image.height);
}
private function btn_rotateCCW_clickHandler(event:MouseEvent):void
{
o_rotateimage.rotateCCW(image);
}
]]>
</fx:Script>
<s:VGroup x="10" y="10">
<s:HGroup>
<s:TextInput id="ti_width" text="300" width="40"/>
<s:TextInput id="ti_height" text="200" width="40"/>
<s:Button label="Resize" click="btn_resize_clickHandler(event)"/>
<s:Button label="Rotate" click="btn_rotateCCW_clickHandler(event)"/>
</s:HGroup>
<s:HGroup width="800" height="600" horizontalAlign="center" verticalAlign="middle">
<s:Image id="image" source="{chartPng}" width="600" height="400"/>
</s:HGroup>
</s:VGroup>
</s:Application>
//RotateImage.as
package com.imageeditor
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.geom.Matrix;
import spark.components.Image;
public class RotateImage
{
private var m:Matrix;
public function rotateCCW(image:Image):void
{
var w:int = image.width;
var h:int = image.height;
m = new Matrix();
m.rotate(Math.PI/2);
m.tx = image.height;
var bd:BitmapData = new BitmapData(image.height as int, image.width as int);
bd.draw(image, m);
image.width = h;
image.height = w;
image.source = new Bitmap(bd);
}
public function scale(image:Image, kx:Number, ky:Number):void
{
var w:int = image.width;
var h:int = image.height;
m = new Matrix();
m.scale(kx, ky);
var bd:BitmapData = new BitmapData(w*kx as int, h*ky as int);
bd.draw(image, m);
image.width = w*kx;
image.height = h*ky;
image.source = new Bitmap(bd);
}
}
}

Related

How to position spark List control below StageWebView in Flex Mobile

I am developing mobile application for iOS and Android using Flex Mobile. On one of the views I am displaying StageWebView with a Google map and a spark List control to display another data. I am using the StageWebView in order to benefit from Google Maps JavaScript API v3. Example code below:
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="Clubs" backgroundAlpha="0"
viewActivate="view1_viewActivateHandler(event)"
backKeyPressed="view1_backKeyPressedHandler(event)"
initialize="view1_initializeHandler(event)">
<fx:Script>
<![CDATA[
import flash.sensors.Geolocation;
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
import spark.events.ViewNavigatorEvent;
private var myWebView:StageWebView;
[Bindable]
private var locations:ArrayCollection;
private var geolocation:Geolocation;
protected function view1_initializeHandler(event:FlexEvent):void
{
myWebView = new StageWebView();
myWebView.stage = this.stage;
}
protected function view1_viewActivateHandler(event:ViewNavigatorEvent):void
{
if(Geolocation.isSupported)
{
geolocation = new Geolocation();
geolocation.addEventListener(GeolocationEvent.UPDATE, onGeolocationChange);
}
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
super.updateDisplayList(unscaledWidth, unscaledHeight);
if (myWebView) {
var point:Point = (new Point());
point = localToGlobal(point);
myWebView.viewPort = new Rectangle(point.x,point.y, stage.width,stage.height/3);
}
}
protected function view1_backKeyPressedHandler(event:Event):void
{
if (myWebView)
{
myWebView.viewPort = null;
myWebView = null;
}
navigator.popView();
}
protected function onGeolocationChange(event:GeolocationEvent):void
{
geolocation.removeEventListener(GeolocationEvent.UPDATE, onGeolocationChange);
locations = new ArrayCollection();
var location0:Object = new Object();
location0.lat = event.latitude;
location0.long = event.longitude;
locations.addItem(location0);
var location1:Object = new Object();
location1.lat = "42.697325";
location1.long = "23.315364";
locations.addItem(location1);
var location2:Object = new Object();
location2.lat = "42.696441";
location2.long = "23.321028";
locations.addItem(location2);
var url:String = "http://whozzzin.dev.mediatecture.at/gmapsformobile/map.php";
var counter:Number = 1;
for each(var location:Object in locations)
{
if(counter == 1)
{
url += "?locations["+counter.toString()+"][lat] = " + location.lat;
url += "&locations["+counter.toString()+"][long] = " + location.long;
}
else
{
url += "&locations["+counter.toString()+"][lat] = " + location.lat;
url += "&locations["+counter.toString()+"][long] = " + location.long;
}
counter++;
}
myWebView.loadURL(url);
}
]]>
</fx:Script>
<s:navigationContent>
<s:Button includeInLayout="{Capabilities.version.indexOf('IOS') > -1}" visible="{Capabilities.version.indexOf('IOS') > -1}" id="backButton" label="BACK" click="view1_backKeyPressedHandler(event)"/>
</s:navigationContent>
<s:List width="100%" contentBackgroundAlpha="0" id="placesList" dataProvider="{locations}" labelField="lat">
<s:layout>
<s:TileLayout columnWidth="{(width - 16)/3}"/>
</s:layout>
</s:List>
</s:View>
Currently the list is not visible because it appears behind the StageWebView. My question is how to position the List control exactly after the WebStageView.
You can use the top constraint:
<s:List width="100%" top="{stage.height/3}" id="placesList"
Edit: Put in a trace(stage.height); in your updateDisplayList function and also look at stage.stageHeight. Those values should help you figure out the exact top value to use in this case.
How I solved it:
I get the bottom of the WebStageView and convert a new point from global to local with x =0 and y = myWebView.bootom:
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
super.updateDisplayList(unscaledWidth, unscaledHeight);
if (myWebView) {
var point:Point = (new Point(0,this.radiusDropDown.height));
point = localToGlobal(point);
myWebView.viewPort = new Rectangle(point.x,point.y, stage.width,stage.height/3);
this.placesList.y = globalToLocal(new Point(0,myWebView.viewPort.bottom)).y;
}
}

Drawing styled text on BitmapData

I have a function that draws a string over BitmapData. The problem is, the TextFormat specified does not affect the text written on the image. The size, font I specify in the text format is not used at all.
function drawString(target:BitmapData,text:String,color:uint,x:Number,y:Number):void {
var channelName:TextField = new TextField();
channelName.textColor=color;
channelName.antiAliasType = AntiAliasType.ADVANCED;
channelName.alpha=1.0;
var txtFormat:TextFormat = new TextFormat("Verdana",25,color,true);
txtFormat.size=Number(25);
txtFormat.font="Verdana";
txtFormat.bold=true;
channelName.setTextFormat(txtFormat);
channelName.text = text;
channelName.defaultTextFormat = txtFormat;
channelName.cacheAsBitmap = true;
channelName.width=400;
var mat:Matrix = new Matrix();
mat.translate(x,y);
target.draw(channelName,mat);
}
How can I customize the text font and size drawn over the BitmapData?
Here is my code:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" width="640" height="400" creationComplete="init(event)">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
[Embed(source='com/drawtext/Image.jpg')]
public var Picture:Class;
protected function init(event:FlexEvent):void
{
var bitmapData:BitmapData = new BitmapData(640, 400, true, 0xFF82DC);
bitmapData.draw(new Picture());
img.source = bitmapData;
drawString(bitmapData, "It is Yours!", 0xff0000, 70, 60);
}
protected function drawString(target:BitmapData,text:String,color:uint,x:Number,y:Number):void
{
var channelName:TextField = new TextField();
channelName.antiAliasType = AntiAliasType.ADVANCED;
var txtFormat:TextFormat = new TextFormat();
txtFormat.size = 35;
txtFormat.font = "Verdana";
txtFormat.bold = true;
channelName.defaultTextFormat = txtFormat;
channelName.width = 400;
channelName.height = 40;
channelName.textColor=color;
channelName.text = text;
var mat:Matrix = new Matrix();
mat.translate(x, y);
target.draw(channelName, mat);
}
]]>
</fx:Script>
<s:Image id="img" width="640" height="400"/>
</s:WindowedApplication>
The result:
Try setting text property before setting text format - and either use setTextFormat(...) or defaultTextFormat = ... not both
And you can also remove these lines too:
//does the same thing as new TextFormat("Verdana",25,color,true)
txtFormat.size=Number(25);
txtFormat.font="Verdana";
txtFormat.bold=true;
//only useful if you add textField to the display list (ie: if you did addChild(channelName)
channelName.cacheAsBitmap = true;

How to draw rectangle in flex 4.5.1?

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="640" minHeight="480">
<s:layout>
<s:BasicLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import flash.display.Shape;
import flash.display.Sprite;
import mx.core.UIComponent;
import spark.core.SpriteVisualElement;
private var rectangle:Sprite = new Sprite();
private var insterter:UIComponent = new UIComponent();
private var theme:SpriteVisualElement = new SpriteVisualElement();
private function main():void
{
rectangle.graphics.lineStyle(1,0x0000FF,1.0);
rectangle.graphics.drawRect(0,0,200,50);
theme.addChild(rectangle);
this.addElement(theme); //tried canvas.addElement
const WIDTH:int = 20;
const HEIGHT:int = 20;
/*var grid:Array = new Array();
for(var y:int = 0; y < HEIGHT; y++) {
var row:Array = new Array();
for (var x:int = 0; x < WIDTH; x++) {
row.push(/*random object*//*);
}
/ grid.push(row);
}*/
}
]]>
</fx:Script>
<!--<spark:Canvas id="canvas" x="34" y="10" width="90%" height="90%" textAlign="center">
</mx:Canvas>-->
</s:Application>
Basically this is not working. I used this question to improve - still nothing.
Why doesnt this Flex App draw a simple rectangle?
Why don't you just use UIComponent.graphics drawing abilities, instead of creating three different objects ?
var uic:UIComponent = new UIComponent();
this.addElement(uic);
uic.width = uic.height = 50;
uic.graphics.lineStyle(1,0x000000);
uic.graphics.drawRect(0,0,50,50);

Loading Swf with bytearray in AIR

We have requirement with the AIR application which loads the flex generated swf which inturn loads the flash generated swf using SWFLoader. This is not working as desired. This gives the following error:
SecurityError: Error #3226: Cannot import a SWF file when LoaderContext.allowCodeImport is false.
This is our AIR application.
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="initApp()">
<mx:Script>
<![CDATA[
import mx.controls.SWFLoader;
[Embed(source="FlexLoadingFlash.swf")]
public var flexMovie:Class;
private function initApp():void {
// First convert the Swf into MovieClip
var movieclip:MovieClip = new flexMovie();
// get the byteArray from movieClip
var byteArray:ByteArray = movieclip.movieClipData;
var swfLoader:SWFLoader = new SWFLoader();
// load bytearray into swfLoader
swfLoader.source = byteArray;
swfLoader.maintainAspectRatio = false;
swfLoader.percentHeight = vbox.height;
swfLoader.percentWidth = vbox.width;
swfLoader.invalidateDisplayList();
swfLoader.invalidateSize();
// now add the swfloader into container
vbox.addChild(swfLoader);
}
]]>
</mx:Script>
<mx:VBox id="vbox" width="100%" height="100%" verticalCenter="0" horizontalCenter="0" cacheAsBitmap="true" >
</mx:VBox>
</mx:WindowedApplication>
Please let me know how can we fix this issue.
Use Loader.loadBytes() to load your SWF. Create an instance of LoaderContext. loadBytes method takes a LoaderContext instance as a parameter. Set the allowCodeImport property of your LoaderContext instance to true and it should work
Or you can just add these three lines before you set the source
var loaderContext: LoaderContext = new LoaderContext();
loaderContext.allowLoadBytesCodeExecution = true;
swfLoader.loaderContext = loaderContext;
<mx:SWFLoader id="swfObj"
width="100%" height="100%"
complete="swfObj_completeHandler(event)"/>
<fx:Script>
<![CDATA[
[Bindable]
[Embed(source="assets/soundbar.swf")]
private static var swfClass:Class;
private var swfSoundBar : MovieClip;
[Bindable] private var mp3Player:MP3Player = MP3Player.getInstance();
protected function init(event:FlexEvent):void
{
swfSoundBar = new swfClass();
var byteArray:ByteArray = swfSoundBar.movieClipData;
var loaderContext: LoaderContext = new LoaderContext();
loaderContext.allowLoadBytesCodeExecution = true;
swfObj.loaderContext = loaderContext;
swfObj.source = byteArray;
}
protected function swfObj_completeHandler(event:Event):void
{
swfSoundBar = SWFLoader(event.target).content as MovieClip;
swfSoundBar.width = 32;
swfSoundBar.height = 14;
swfSoundBarShowHide();
}
protected function swfSoundBarShowHide():void
{
if (swfSoundBar){
if (mp3Player.isPlaying){
swfSoundBar.gotoAndStop(0);
swfSoundBar.stop();
} else {
swfSoundBar.gotoAndPlay(0);
}
}
}
]]>
</fx:Script>

Is there a way to add a link text or button to the panel header along with the panel title in Flex?

I have a panel in my application. My requirement is, I also require a link, that is "Help options" to appear in the panel's header. In the left, we will have the Panel's title and in the right corner, I need this link. Is that possible?
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
width="400" height="300" label="Panel's Label">
<mx:Script>
<![CDATA[
private var linkTextField:TextField;
private var _linkHtmlText:String = "";
public function set linkHtmlText(value:String):void
{
_linkHtmlText = value;
if(linkTextField)
linkTextField.htmlText = value;
}
override protected function createChildren():void
{
super.createChildren();
linkTextField = new TextField();
linkTextField.autoSize = TextFieldAutoSize.LEFT;
linkTextField.text = _linkHtmlText;
linkTextField.y = 5;
this.titleBar.addChild(linkTextField);
}
override protected function layoutChrome(unscaledWidth:Number,
unscaledHeight:Number):void
{
super.layoutChrome(unscaledWidth, unscaledHeight);
linkTextField.x = unscaledWidth - linkTextField.width - 10;
}
]]>
</mx:Script>
</mx:Panel>
import mx.core.IUITextField;
function init():void{
var rightpanel_ui:IUITextField = rightpanel.mx_internal::getStatusTextField();
rightpanel_ui.selectable = true;
rightpanel_ui.htmlText = "<a href='/mylink.php/' target='_new'><u><font color='white'>Help</font></u></a>";
}
<mx:Panel id="rightpanel" width="100%" height="100%" status="Help">

Resources