StageWebView - 如何防止通过drawViewPortToBitmapData获得的位图的拉伸?

时间:2011-11-04 00:30:22

标签: flex

我正在尝试使用StageWebView作为位图显示显示的页面。根据文档,我们需要使用DrawViewPortToBitMapData。在显示位图时 UIComponent,图像越来越紧张。我怎么能防止这种情况?

bitmapData = new BitmapData(webView.viewPort.width, webView.viewPort.height, false,
0x000000 );
webView.drawViewPortToBitmapData(bitmapData);
webViewBmp = new Bitmap(bitmapData); 
webView.stage = null;

uiComponent = new UIComponent;
uiComponent.width=webView.viewPort.width;
uiComponent.height=webView.viewPort.height;
uiComponent.addChild(webViewBmp); 

4 个答案:

答案 0 :(得分:0)

我认为你不需要对uicomponent应用宽度/高度。只需将位图添加到它就可以了。即使您已经以正确的大小添加了位图,您似乎正在做的是拉伸uicomponent。

答案 1 :(得分:0)

您应该在uiComponet上将scale设置为1。如果设置applicationDPI(假设为160dpi),Flex会根据设备DPI自动调整uiComponent,将scaleX和scaleY设置为runtimeDPI / 160.

尝试这样的事情:

uiComponent.scaleX = 160 / parentApplication.runtimeDPI; uiComponent.scaleY = 160 / parentApplication.runtimeDPI;

因此scaleX和scaleY以:

结束

runtimeDPI / 160(由flex完成)* 160 / runtimeDPI = 1:)

答案 2 :(得分:0)

我知道这是旧的,但这对我有用:

        var r:Rectangle = wView.viewPort;
        var bd:BitmapData = new BitmapData(r.width, r.height);
        wView.drawViewPortToBitmapData(bd);
        var bmp:Bitmap = new Bitmap(bd);
        bmp.width = bd.width * (Capabilities.screenResolutionX / 320);
        bmp.height = bd.height * (Capabilities.screenResolutionY / 480);

希望它有所帮助!

答案 3 :(得分:0)

使用uiComponent.unscaledWidth& unscaledHeight属性。这是我的工作组件,改变了flexcapacitor代码 - 原文:http://flexcapacitor.googlecode.com/svn-history/r5/trunk/mobilelibrary/src/com/flexcapacitor/controls/WebView.as

看看takeSnapshot:

    snapshotBitmapData = new BitmapData(_webView.viewPort.width, _webView.viewPort.height);
    webView.drawViewPortToBitmapData(snapshotBitmapData);
    webViewBitmap = new Bitmap(snapshotBitmapData);
    webViewBitmap.width = unscaledWidth;
    webViewBitmap.height = unscaledHeight;
    addChild(webViewBitmap);
    hideWebView(); 

完整代码:

package ctrls {

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.ErrorEvent;
import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.KeyboardEvent;
import flash.events.LocationChangeEvent;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.media.StageWebView;
import flash.ui.Keyboard;

import mx.core.FlexGlobals;
import mx.core.UIComponent;

/** @copy flash.media.StageWebView#ErrorEvent.ERROR */
[Event(name="error", type="flash.events.ErrorEvent")]
/** @copy flash.media.StageWebView#Event.COMPLETE */
[Event(name="complete", type="flash.events.Event")]
/** @copy flash.media.StageWebView#LocationChangeEvent.LOCATION_CHANGING */
[Event(name="locationChanging", type="flash.events.LocationChangeEvent")]
/** @copy flash.media.StageWebView#LocationChangeEvent.LOCATION_CHANGE */
[Event(name="locationChange", type="flash.events.LocationChangeEvent")]

/**
 * This class wraps the standard StageWebView with a UIComponent.
 * This allows it to be sized and positioned in the same way
 * any UIComponent would. <br/><br/>
 *
 * The StageWebView class documentation follows:<br/>
 * @copy flash.media.StageWebView
 * */
public class WebView extends UIComponent {

//==================================================================================================

protected var _webView:StageWebView;
private var _source:String;
private var _visibleChanged:Boolean;
private var _sourceChanged:Boolean;

/** @copy flash.media.StageWebView#viewPort */
public function get viewPort():Rectangle { return _webView ? _webView.viewPort : null; }
/** @copy flash.media.StageWebView#dispose() */
public function dispose():void { hideWebView(true); }
/** @copy flash.media.StageWebView#assignFocus() */
public function assignFocus(direction:String = "none"):void { webView.assignFocus(direction); }
/** @copy flash.media.StageWebView#drawViewPortToBitmapData() */
public function drawViewPortToBitmapData(bitmap:BitmapData):void { webView.drawViewPortToBitmapData(bitmap); }
/** @copy flash.media.StageWebView#title */
public function get title():String { return _webView ? _webView.title : null; }

/** @copy flash.media.StageWebView#isHistoryBackEnabled() */
public function get isHistoryBackEnabled():Boolean { return _webView ? _webView.isHistoryBackEnabled : false; }
/** @copy flash.media.StageWebView#isHistoryForwardEnabled() */
public function get isHistoryForwardEnabled():Boolean { return _webView ? _webView.isHistoryForwardEnabled : false; }
/** @copy flash.media.StageWebView#historyBack() */
public function historyBack():void { if(_webView) _webView.historyBack(); }
/** @copy flash.media.StageWebView#historyForward() */
public function historyForward():void { if(_webView) _webView.historyForward(); }
/** @copy flash.media.StageWebView#reload() */
public function reload():void { webView.reload(); }
/** @copy flash.media.StageWebView#stop() */
public function stop():void { if(_webView) webView.stop(); }
/** Load the URL passed in or load the URL specified in the source property
 *  @see flash.media.StageWebView#loadURL() */
public function load(url:String = null):void { webView.loadURL(url ? _source = url : source); }

override public function set visible(value:Boolean):void {
    super.visible = value;
    _visibleChanged = true;
    invalidateProperties();
    invalidateSize();
}
/** @private */
public function get source():String { return _source; }
/**
 * Source URL for stage web view.
 * @see flash.media.StageWebView#loadURL()
 * */
[Bindable]
public function set source(value:String):void {
    _source = value;
    _sourceChanged = true;
    invalidateProperties();
    invalidateSize();
}

//==================================================================================================

/**
 *  Wrapper for StageWebView
 *
 *  @copy flash.media.StageWebView
 */
public function WebView() {
    addEventListener(Event.ADDED_TO_STAGE, addedToStage);
    addEventListener(Event.REMOVED_FROM_STAGE, removedFromStage);
    focusEnabled = false;
}

/** @private */
public function get webView():StageWebView {
    if(!_webView) webView = new StageWebView();
    return _webView; }
/** @copy flash.media.StageWebView */
public function set webView(value:StageWebView):void {
    if(_webView == value) return;
    if(_webView) {
        _webView.removeEventListener(Event.COMPLETE, completeHandler);
        _webView.removeEventListener(ErrorEvent.ERROR, errorHandler);
        _webView.removeEventListener(FocusEvent.FOCUS_IN, focusInViewHandler);
        _webView.removeEventListener(FocusEvent.FOCUS_OUT, focusOutViewHandler);
        _webView.removeEventListener(LocationChangeEvent.LOCATION_CHANGING, locationChangingHandler);
        _webView.removeEventListener(LocationChangeEvent.LOCATION_CHANGE, locationChangeHandler); }
    _webView = value;
    _webView.addEventListener(Event.COMPLETE, completeHandler);
    _webView.addEventListener(ErrorEvent.ERROR, errorHandler);
    _webView.addEventListener(FocusEvent.FOCUS_IN, focusInViewHandler);
    _webView.addEventListener(FocusEvent.FOCUS_OUT, focusOutViewHandler);
    _webView.addEventListener(LocationChangeEvent.LOCATION_CHANGING, locationChangingHandler);
    _webView.addEventListener(LocationChangeEvent.LOCATION_CHANGE, locationChangeHandler);
    _webView.stage = visible ? stage : null;
    _visibleChanged = false;
    if(source) _webView.loadURL(_source);
    _sourceChanged = false;
    invalidateDisplayList();
}
/** Hides the web view @see flash.media.StageWebView#stage */
public function hideWebView(destroy:Boolean = false):void {
    if(_webView == null) return;
    _webView.stage = null;
    if(!destroy) return;
    _webView.viewPort = null;
    _webView.dispose();
    _webView = null;
}
/** Displays the web view @see flash.media.StageWebView#stage */
public function showWebView():void {
    if(_webView != null) {
        webView.stage = stage;
        return; }
    _visibleChanged = true;
    invalidateProperties();
    invalidateSize();
    invalidateDisplayList(); }
/** @copy mx.core.UIComponent#commitProperties() */
override protected function commitProperties():void {
    super.commitProperties();
    if(_visibleChanged) {
        webView.stage =  visible ? stage : null;
        _visibleChanged = false; }
    if(_sourceChanged) {
        webView.loadURL(source);
        _sourceChanged = false; }}

//==================================================================================================

/** Flag indicating if a snapshot is being shown */
[Bindable]
public var isSnapshotVisible:Boolean;
/**
 * When calling takeSnapshot or setting snapshotMode to true this 
 * property will contain the bitmap data of the view port. 
 * */
public var snapshotBitmapData:BitmapData;
/**
 * When calling takeSnapshot or setting snapshotMode a snapshot of 
 * the Stage Web View is taken and added to the stage. This is a
 * reference to the displayed bitmap. 
 * */
public var webViewBitmap:Bitmap;
/**
 * @private
 * */
public function get snapshotMode():Boolean {
    return isSnapshotVisible;
}
/**
 * When set to true hides the stage web view and displays a non-interactive 
 * snapshot of the Stage Web View when the property was set to true.  
 * */
public function set snapshotMode(value:Boolean):void {
    value ? takeSnapshot() : removeSnapshot();
}
/**
 * Creates a snapshot of the Stage Web View at the point of this call 
 * and displays that instead of the actual Stage Web View. 
 * Use removeSnapshot to dispose of the snapshot and show the web contents again. 
 * 
 * @see isSnapshotVisible
 * @see flash.media.StageWebView#drawViewPortToBitmapData()
 * */
public function takeSnapshot():BitmapData {
    destroySnapshot();
    snapshotBitmapData = new BitmapData(_webView.viewPort.width, _webView.viewPort.height);
    webView.drawViewPortToBitmapData(snapshotBitmapData);
    webViewBitmap = new Bitmap(snapshotBitmapData);
    webViewBitmap.width = unscaledWidth;
    webViewBitmap.height = unscaledHeight;
    addChild(webViewBitmap);
    hideWebView(); 
    isSnapshotVisible = true;

    return snapshotBitmapData;
}
/**
 * Removes the bitmap snapshot of the Stage Web View from the display list 
 * and displays the actual Stage Web View.
 * @copy flash.media.StageWebView#drawViewPortToBitmapData()
 * */
public function removeSnapshot():void {
    destroySnapshot();
    showWebView();
}
/**
 * Removes the web view snapshot from the display list and disposes of the 
 * bitmap data
 * */
private function destroySnapshot():void {
    if (webViewBitmap) {
        if (webViewBitmap.parent) removeChild(webViewBitmap);
        if (webViewBitmap.bitmapData) webViewBitmap.bitmapData.dispose();
        webViewBitmap = null;
    }
    if (snapshotBitmapData) {
        snapshotBitmapData.dispose();
        snapshotBitmapData = null;
    }
    isSnapshotVisible = false;
}

//==================================================================================================

/**
 * If enabled adds support for the back and search keys.
 * Back key navigates back in web view history and search navigates forward.
 * */
public var navigationSupport:Boolean;
/**
 * If enabled adds a keyboard listener to the stage.
 * This handles when the component does not have focus
 * */
public var addKeyHandlerToStage:Boolean;
/**
 * KeyCode to use when navigation support is enabled.
 * Default is Keyboard.BACK
 * */
public var backKeyCode:int = Keyboard.BACK;
/**
 * KeyCode to use when navigation support is enabled.
 * Default is Keyboard.SEARCH
 * */
public var forwardKeyCode:int = Keyboard.SEARCH;
/**
 * @copy mx.core.UIComponent#measure()
 * */
override protected function measure():void {
    super.measure();

    measuredWidth=480;
    measuredMinWidth=120;
    measuredHeight=320;
    measuredMinHeight=160;
}
/**
 * @copy mx.core.UIComponent#updateDisplayList()
 * */
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
// NOTE: IF THE WEBVIEW IS NOT BEING SIZED CORRECTLY
// check if focusEnabled is true. If it is then the soft keyboard may not be dispatching the
// deactivate event because the webview has focus when it is dispatched. set to false
// position according to the container rather than the stage
    var runtimeDPI:int = FlexGlobals.topLevelApplication.runtimeDPI;
    var applicationDPI:int = FlexGlobals.topLevelApplication.applicationDPI;
    var point:Point = localToGlobal(new Point());
    var scaleFactor:Number = runtimeDPI / applicationDPI;
    var scaledWidth:int = width * scaleFactor;
    var scaledHeight:int = height * scaleFactor;
    webView.viewPort = new Rectangle(point.x, point.y, scaledWidth, scaledHeight);
}

//--------------------------------------------------------------------------
//
//  Event handlers
//
//--------------------------------------------------------------------------

/** When the stage property is available add it to the web view */
public function addedToStage(event:Event):void {
//  adds support for keyboard events when not in focus
    if (navigationSupport && addKeyHandlerToStage)
        stage.addEventListener( KeyboardEvent.KEY_DOWN, keyDownHandler);
    _visibleChanged = true;
    invalidateProperties();
    invalidateDisplayList();
}
/** When removed from the stage remove the web view */
protected function removedFromStage(event:Event):void {
    hideWebView();
//  removes support for keyboard events when not in focus
    if (navigationSupport && addKeyHandlerToStage)
        stage.removeEventListener( KeyboardEvent.KEY_DOWN, keyDownHandler );
}
/** Dispatches a focus in event when the web view gains focus. */
protected function focusInViewHandler(event:FocusEvent):void {
    //webView.assignFocus();

    if (hasEventListener(event.type))
        dispatchEvent(event);

}
/** Dispatches a focus out event when the web view gains focus. */
protected function focusOutViewHandler(event:FocusEvent):void {
    //webView.assignFocus(FocusDirection.TOP);

    if (hasEventListener(event.type))
        dispatchEvent(event);
}
/** Dispatches a focus in event when the web view gains focus. */
override protected function keyDownHandler(event:KeyboardEvent):void {

    if (navigationSupport) {
        if (event.keyCode == backKeyCode && webView.isHistoryBackEnabled ) {
            webView.historyBack();
            event.preventDefault();
        }

        if (navigationSupport && event.keyCode == forwardKeyCode && webView.isHistoryForwardEnabled ) {
            webView.historyForward();
        }
    }

    super.keyDownHandler(event);
}

/** Dispatched when the page or web content has been fully loaded */
protected function completeHandler(event:Event):void {
    if(hasEventListener(event.type)) dispatchEvent(event); }
/** Dispatched when the location is about to change */
protected function locationChangingHandler(event:Event):void {
    if(hasEventListener(event.type)) dispatchEvent(event); }
/** Dispatched when the location has changed */
protected function locationChangeHandler(event:Event):void {
    if(hasEventListener(event.type)) dispatchEvent(event); }
/** Dispatched when an error occurs */
protected function errorHandler(event:ErrorEvent):void {
    if(hasEventListener(event.type)) dispatchEvent(event); }

}}