Created
March 23, 2012 18:24
-
-
Save JesterXL/2173475 to your computer and use it in GitHub Desktop.
class used to magnify a portion of Strobe video
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.thirdiris.viaasplayer.components | |
{ | |
import com.bit101.components.Component; | |
import com.thirdiris.viaasplayer.events.view.VideoMagnifierEvent; | |
import flash.display.Bitmap; | |
import flash.display.BitmapData; | |
import flash.display.BlendMode; | |
import flash.display.DisplayObjectContainer; | |
import flash.display.Graphics; | |
import flash.display.Shape; | |
import flash.display.Sprite; | |
import flash.events.Event; | |
import flash.events.MouseEvent; | |
import flash.geom.Matrix; | |
import flash.geom.Point; | |
import flash.geom.Rectangle; | |
import flash.media.Video; | |
import flash.text.TextField; | |
import flash.text.TextFormat; | |
import org.osmf.media.videoClasses.VideoSurface; | |
import spark.primitives.Rect; | |
[Event(name="closeClicked", type="com.thirdiris.viaasplayer.events.view.VideoMagnifierEvent")] | |
public class VideoMagnifier extends Component | |
{ | |
private static const BITMAP_WIDTH:Number = 201; | |
private static const BITMAP_HEIGHT:Number = 134; | |
[Embed(source="/assets/viaasimages/magnifier-background.png")] | |
private var MagnifierBackground:Class; | |
[Embed(source="/assets/viaasimages/button-close.png")] | |
private var ButtonClose:Class; | |
private var _videoSurface:VideoSurface; | |
private var videoSurfaceDirty:Boolean = false; | |
private var ticker:Sprite; | |
private var backgroundImage:Bitmap; | |
private var background:Sprite; | |
private var bitmap:Bitmap; | |
private var bitmapData:BitmapData; | |
private var originalBitmapData:BitmapData; | |
private var maskShape:Shape; | |
private var closeButton:Sprite; | |
private var titleField:TextField; | |
private var zoomLabel:TextField; | |
private var zoomSlider:Slider; | |
private var debugTicker:Sprite; | |
private var centerPoint:Point = new Point(); | |
private var zoomRectangle:Rectangle = new Rectangle(); | |
private var targetPoint:Point = new Point(0, 0); | |
private var dragging:Boolean = false; | |
private var scaleMatrix:Matrix; | |
private var magnification:Number = 2; | |
private var videoIsTooSmall:Boolean = false; | |
//private var video:Video; | |
public function get videoSurface():VideoSurface { return _videoSurface; } | |
public function set videoSurface(value:VideoSurface):void | |
{ | |
if(value !== _videoSurface) | |
{ | |
_videoSurface = value; | |
videoSurfaceDirty = true; | |
// [jwarden 3.2.2012] KLUDGE: I love Strobe. | |
//video = _videoSurface.getChildAt(0) as Video; | |
invalidateProperties(); | |
} | |
} | |
public function VideoMagnifier(parent:DisplayObjectContainer=null, xpos:Number=0, ypos:Number=0) | |
{ | |
super(parent, xpos, ypos); | |
addEventListener(Event.ADDED_TO_STAGE, onAdded); | |
addEventListener(Event.REMOVED_FROM_STAGE, onRemoved); | |
} | |
private function onAdded(event:Event):void | |
{ | |
if(debugTicker == null) | |
{ | |
debugTicker = new Sprite(); | |
stage.addChild(debugTicker); | |
debugTicker.addEventListener(Event.ENTER_FRAME, onDebugDraw); | |
} | |
} | |
private function onRemoved(event:Event):void | |
{ | |
if(debugTicker) | |
{ | |
stage.removeChild(debugTicker); | |
debugTicker.removeEventListener(Event.ENTER_FRAME, onDebugDraw); | |
debugTicker = null; | |
} | |
} | |
public function destroy():void | |
{ | |
stopDrag(); | |
_videoSurface = null; | |
stopDrawing(); | |
removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); | |
removeEventListener(MouseEvent.MOUSE_UP, onMouseUp); | |
if(stage) | |
{ | |
stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp); | |
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); | |
} | |
if(bitmapData) | |
{ | |
bitmapData.dispose(); | |
bitmapData = null; | |
} | |
if(bitmap) | |
bitmap = null; | |
if(originalBitmapData) | |
{ | |
originalBitmapData.dispose(); | |
originalBitmapData = null; | |
} | |
} | |
protected override function init():void | |
{ | |
//width = 223; | |
//height = 225; | |
width = BITMAP_WIDTH; | |
height = BITMAP_HEIGHT; | |
tabEnabled = false; | |
buttonMode = useHandCursor = true; | |
name = "VideoMagnifier"; | |
super.init(); | |
} | |
protected override function addChildren():void | |
{ | |
super.addChildren(); | |
ticker = new Sprite(); | |
background = new Sprite(); | |
addChild(background); | |
//background.blendMode = BlendMode.INVERT; | |
background.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); | |
background.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); | |
backgroundImage = new MagnifierBackground() as Bitmap; | |
addChild(backgroundImage); | |
backgroundImage.x = 1; | |
backgroundImage.y = 6; | |
maskShape = new Shape(); | |
addChild(maskShape); | |
maskShape.x = 8; | |
maskShape.y = 30; | |
closeButton = new Sprite(); | |
addChild(closeButton); | |
closeButton.tabChildren = closeButton.mouseChildren = false; | |
closeButton.buttonMode = closeButton.useHandCursor = true; | |
closeButton.addChild(new ButtonClose()); | |
closeButton.addEventListener(MouseEvent.CLICK, onCloseButtonClicked); | |
closeButton.x = 208; | |
closeButton.y = 1; | |
titleField = new TextField(); | |
addChild(titleField); | |
titleField.selectable = false; | |
titleField.tabEnabled = titleField.mouseEnabled = titleField.mouseWheelEnabled = false; | |
var headerFMT:TextFormat = new TextFormat(); | |
headerFMT.font = "Helvetica Neue"; | |
headerFMT.size = 14; | |
headerFMT.color = 0x333333; | |
titleField.defaultTextFormat = headerFMT; | |
titleField.text = "Magnifier"; | |
titleField.x = (backgroundImage.width / 2) - ((titleField.textWidth + 4) / 2); | |
titleField.y = 9; | |
zoomLabel = new TextField(); | |
addChild(zoomLabel); | |
zoomLabel.selectable = false; | |
zoomLabel.tabEnabled = zoomLabel.mouseEnabled = zoomLabel.mouseWheelEnabled = false; | |
var zoomFormat:TextFormat = new TextFormat(); | |
zoomFormat.size = 11; | |
zoomFormat.color = 0x333333; | |
zoomFormat.font = "Helvetica Neue"; | |
zoomLabel.defaultTextFormat = zoomFormat; | |
zoomLabel.text = "Zoom:"; | |
zoomLabel.x = 12; | |
zoomLabel.y = 199; | |
zoomSlider = new Slider(this); | |
addChild(zoomSlider); | |
zoomSlider.initialize(2, 1, 10); | |
zoomSlider.addEventListener(Event.CHANGE, onZoomChange); | |
zoomSlider.x = 52; | |
zoomSlider.y = 198; | |
} | |
protected override function commitProperties():void | |
{ | |
super.commitProperties(); | |
if(videoSurfaceDirty) | |
{ | |
videoSurfaceDirty = false; | |
if(videoSurface) | |
{ | |
createBitmap(); | |
startDrawing(); | |
} | |
else | |
{ | |
stopDrawing(); | |
} | |
} | |
} | |
public override function draw():void | |
{ | |
super.draw(); | |
var g:Graphics = background.graphics; | |
g.clear(); | |
//g.beginFill(0x333333, .7); | |
//g.drawRoundRect(-10, -10, width + 20, height + 20, 12, 12); | |
g.lineStyle(2, 0xFF0000); | |
g.beginFill(0x000000, 0); | |
g.drawRect(0, 0, width, height); | |
g.endFill(); | |
g = maskShape.graphics; | |
g.clear(); | |
g.beginFill(0x00FF00, .5); | |
g.drawRect(0, 0, BITMAP_WIDTH, BITMAP_HEIGHT); | |
g.endFill(); | |
createBitmap(); | |
} | |
private function createBitmap():void | |
{ | |
if(bitmapData) | |
bitmapData.dispose(); | |
if(originalBitmapData) | |
originalBitmapData.dispose(); | |
if(videoSurface.videoWidth > 0 && videoSurface.videoHeight > 0) | |
{ | |
videoIsTooSmall = false; | |
} | |
else | |
{ | |
videoIsTooSmall = true; | |
return; | |
} | |
bitmapData = new BitmapData(BITMAP_WIDTH, BITMAP_HEIGHT, false, 0); | |
//originalBitmapData = new BitmapData(videoSurface.videoWidth, videoSurface.videoHeight, false, 0); | |
originalBitmapData = new BitmapData(2880, 2880, false, 0); | |
if(bitmap == null) | |
{ | |
bitmap = new Bitmap(bitmapData, "auto", true); | |
//addChildAt(bitmap, 0); | |
//bitmap.mask = maskShape; | |
addChild(bitmap); | |
} | |
else | |
{ | |
bitmap.bitmapData = bitmapData; | |
} | |
} | |
private function startDrawing():void | |
{ | |
stopDrawing(); | |
ticker.addEventListener(Event.ENTER_FRAME, onTick); | |
} | |
private function stopDrawing():void | |
{ | |
ticker.removeEventListener(Event.ENTER_FRAME, onTick); | |
} | |
private function onTick(event:Event):void | |
{ | |
if(videoIsTooSmall) | |
{ | |
if(videoSurface.videoWidth > 0 && videoSurface.videoHeight > 0) | |
{ | |
videoIsTooSmall = false; | |
createBitmap(); | |
} | |
else | |
{ | |
return; | |
} | |
} | |
var video:Video = videoSurface.getChildAt(0) as Video; | |
if(video) | |
{ | |
// jwarden's algorithm | |
/* | |
originalBitmapData.draw(video, video.transform.matrix); | |
centerPoint.x = x; | |
centerPoint.y = y; | |
centerPoint = parent.localToGlobal(centerPoint); | |
centerPoint = video.parent.globalToLocal(centerPoint); | |
zoomRectangle.x = centerPoint.x; | |
zoomRectangle.y = centerPoint.y; | |
zoomRectangle.width = width; | |
zoomRectangle.height = height; | |
bitmapData.copyPixels(originalBitmapData, zoomRectangle, targetPoint); | |
bitmap.width = width * magnification; | |
bitmap.height = height * magnification; | |
bitmap.x = (width / 2) - (bitmap.width / 2) + maskShape.x; | |
bitmap.y = (height / 2) - (bitmap.height / 2) + maskShape.y; | |
*/ | |
// jwarden's 2nd algo | |
originalBitmapData.draw(video, video.transform.matrix); | |
/* | |
xPos: 0, yPos: 300, zoomArea: (x=0, y=300, w=280, h=180), zoomControl.currentWidth: 300, zoomControl.currentHeight: 200, zoomControl.imageCanvas.width: 280, zoomControl.imageCanvas.height: 180 | |
zoomControl.zoomImage.x: 0, zoomControl.zoomImage.y: 0, zoomControl.zoomImage.width: 280, zoomControl.zoomImage.height: 180 | |
*/ | |
var point:Point = new Point(x, y); | |
point = localToGlobal(point); | |
point = videoSurface.globalToLocal(point); | |
var xPos:Number = point.x - videoSurface.x; | |
var yPos:Number = point.y - videoSurface.y; | |
var zoomArea:Rectangle = new Rectangle(xPos, yPos, BITMAP_WIDTH, BITMAP_HEIGHT); | |
bitmapData.copyPixels(originalBitmapData, zoomArea, targetPoint); | |
bitmap.width = width * magnification; | |
bitmap.height = height * magnification; | |
bitmap.x = (BITMAP_WIDTH - bitmap.width) * (xPos / (videoSurface.videoWidth - BITMAP_WIDTH)); | |
bitmap.y = (BITMAP_HEIGHT - bitmap.height) * (yPos / (videoSurface.videoHeight - BITMAP_HEIGHT)); | |
/* | |
bitmap.width = width * magnification; | |
bitmap.height = height * magnification; | |
bitmap.x = (width / 2) - (bitmap.width / 2) + maskShape.x; | |
bitmap.y = (height / 2) - (bitmap.height / 2) + maskShape.y; | |
*/ | |
// jmiranda's algo from Loki | |
/* | |
bmd = new BitmapData(720,480,true,0); | |
clipMatrix = new Matrix(); | |
clipMatrix.tx = -32; | |
clipMatrix.ty = -45; | |
bmd.draw(controlState, clipMatrix); | |
// Based off the zoom control | |
var xPos:Number = zoomControl.currentX; | |
var yPos:Number = zoomControl.currentY; | |
var zoomArea:Rectangle = new Rectangle(xPos, yPos, zoomControl.currentWidth - 20, zoomControl.currentHeight - 20); | |
var finalBMD:BitmapData = new BitmapData(zoomControl.currentWidth - 20, zoomControl.currentHeight - 20,false,0); | |
finalBMD.copyPixels(bmd, zoomArea, new Point(0,0)); | |
zoomBitmap = new Bitmap(finalBMD,"auto",true); | |
zoomControl.zoomImage.width = (zoomControl.currentWidth - 20) * zoomControl.zoom.value; | |
zoomControl.zoomImage.height = (zoomControl.currentHeight - 20) * zoomControl.zoom.value; | |
zoomControl.zoomImage.x = (zoomControl.imageCanvas.width - zoomControl.zoomImage.width) * (zoomControl.currentX / (740 - zoomControl.currentWidth)); | |
zoomControl.zoomImage.y = (zoomControl.imageCanvas.height - zoomControl.zoomImage.height) * (zoomControl.currentY / (500 - zoomControl.currentHeight)); | |
*/ | |
} | |
} | |
private function onDebugDraw(event:Event):void | |
{ | |
var g:Graphics = debugTicker.graphics; | |
g.clear(); | |
if(videoSurface && originalBitmapData && centerPoint && zoomRectangle && bitmap) | |
{ | |
var video:Video = videoSurface.getChildAt(0) as Video; | |
if(video) | |
{ | |
g.lineStyle(0, 0xFFFFFF); | |
g.moveTo(videoSurface.x, videoSurface.y); | |
g.drawRect(videoSurface.x, videoSurface.y, videoSurface.width, videoSurface.height); | |
g.lineStyle(2, 0xFF0000); | |
g.moveTo(video.x, video.y); | |
g.drawRect(video.x, video.y, video.videoWidth, video.videoHeight); | |
g.lineStyle(2, 0x0000FF); | |
g.moveTo(zoomRectangle.x, zoomRectangle.y); | |
g.drawRect(zoomRectangle.x, zoomRectangle.y, zoomRectangle.width, zoomRectangle.height); | |
g.endFill(); | |
} | |
} | |
} | |
/* | |
private function drawZoom(event:Event):void { | |
bmd = new BitmapData(720,480,true,0); | |
clipMatrix = new Matrix(); | |
clipMatrix.tx = -32; | |
clipMatrix.ty = -45; | |
bmd.draw(controlState, clipMatrix); | |
// Based off the zoom control | |
var xPos:Number = zoomControl.currentX; | |
var yPos:Number = zoomControl.currentY; | |
var zoomArea:Rectangle = new Rectangle(xPos, yPos, zoomControl.currentWidth - 20, zoomControl.currentHeight - 20); | |
var finalBMD:BitmapData = new BitmapData(zoomControl.currentWidth - 20, zoomControl.currentHeight - 20,false,0); | |
finalBMD.copyPixels(bmd, zoomArea, new Point(0,0)); | |
zoomBitmap = new Bitmap(finalBMD,"auto",true); | |
zoomControl.zoomImage.width = (zoomControl.currentWidth - 20) * zoomControl.zoom.value; | |
zoomControl.zoomImage.height = (zoomControl.currentHeight - 20) * zoomControl.zoom.value; | |
zoomControl.zoomImage.x = (zoomControl.imageCanvas.width - zoomControl.zoomImage.width) * (zoomControl.currentX / (740 - zoomControl.currentWidth)); | |
zoomControl.zoomImage.y = (zoomControl.imageCanvas.height - zoomControl.zoomImage.height) * (zoomControl.currentY / (500 - zoomControl.currentHeight)); | |
} | |
*/ | |
private function onMouseDown(event:MouseEvent):void | |
{ | |
if(dragging == false) | |
{ | |
dragging = true; | |
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp, false, 0, true); | |
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove, false, 0, true); | |
var bounds:Rectangle = new Rectangle(videoSurface.x, videoSurface.y, videoSurface.width - width, videoSurface.height - height); | |
startDrag(false, bounds); | |
} | |
} | |
private function onMouseMove(event:MouseEvent):void | |
{ | |
event.updateAfterEvent(); | |
} | |
private function onMouseUp(event:MouseEvent):void | |
{ | |
if(dragging) | |
{ | |
dragging = false; | |
stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp); | |
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); | |
stopDrag(); | |
} | |
} | |
private function onCloseButtonClicked(event:MouseEvent):void | |
{ | |
dispatchEvent(new VideoMagnifierEvent(VideoMagnifierEvent.CLOSE_CLICKED)); | |
} | |
private function onZoomChange(event:Event):void | |
{ | |
magnification = zoomSlider.value; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment