apache-flex 缩放图像导致AS3 Flex AIR移动的应用程序崩溃

798qvoo8  于 2022-11-01  发布在  Apache
关注(0)|答案(1)|浏览(159)

问题:

通过使用矩阵缩放和移动来放大图像会导致应用程序内存不足并崩溃。

使用的其他程式库:

手势-https://github.com/fljot/Gestouch

说明:

在我的Flex移动的应用程序中,我使用Gestouch库在组内启用了平移/缩放的图像。缩放在一定程度上有效,但在特定缩放级别后导致应用程序死亡(不是冻结,只是退出),没有错误消息。
这是可以管理的,除了我不知道如何实现一个阈值来停止缩放,因为它崩溃在一个不同的缩放水平几乎每一次。我也使用动态图像,所以图像源可以是任何大小或分辨率。
它们通常是JPEGS,范围大约在800 x600 - 9000 x6000之间,并且是从服务器下载的,因此不能与应用程序打包。
从AS 3文档开始,BitmapData对象的大小不再有限制,因此这不应该是问题所在。
从AIR 3和Flash player 11开始,已删除BitmapData对象的大小限制。位图的最大大小现在取决于操作系统。
该组将用作标记层,用于在其上叠加管脚。
崩溃主要发生在iPad Mini和较旧的Android设备上。

我已经尝试过的事情

1.使用Adobe Scout确定内存泄漏发生的时间。
2.调试以查找崩溃时标记层和图像的准确高度和宽度。
3.根据图像的大小设置最大缩放变量。
4.缩放时裁剪图像以仅显示可见区域。(copyPixels函数和BitmapData.draw()函数崩溃)
5.使用imagemagick制作质量较低的图像(小图像仍会崩溃)
6.使用imagemagick制作分辨率很低的图像,并制作一个小图像的网格。在移动的应用程序中使用列表和平铺布局显示。
7.在添加事件侦听器时使用弱引用。
如有任何建议,我们将不胜感激。
谢谢

private function layoutImageResized(e: Event):void
        {
            markerLayer.scaleX = markerLayer.scaleY = 1;
            markerLayer.x = markerLayer.y = 0;

            var scale: Number = Math.min(width / image.sourceWidth , height / image.sourceHeight);              
            image.scaleX = image.scaleY = scale;                
            _imageIsWide = (image.sourceWidth / image.sourceHeight) > (width / height);

            // centre image
            if(_imageIsWide)
            {
                markerLayer.y =  (height - image.sourceHeight * image.scaleY ) / 2 ;
            }
            else
            {
                markerLayer.x = (width -image.sourceWidth * image.scaleX ) / 2 ;
            }   
            // set max scale                                
            _maxScale = scale*_maxZoom;         
        }

private function onGesture(event:org.gestouch.events.GestureEvent):void
        {
            trace("Gesture start");
            // if the user starts moving around while the add Pin option is up 
            // the state will be changed and the menu will disappear
            if(currentState == "addPin")
            {
                return;
            }

            const gesture:TransformGesture = event.target as TransformGesture;                  
            ////trace("gesture state is ", gesture.state);
            if(gesture.state == GestureState.BEGAN)
            { 
                currentState = "zooming";

                imgOldX = image.x;
                imgOldY = image.y;

                oldImgWidth = markerLayer.width;
                oldImgHeight = markerLayer.height;

                if(!_hidePins)
                {
                    showHidePins(false);
                }                   
            }

            var matrix:Matrix = markerLayer.transform.matrix;
            // Pan
            matrix.translate(gesture.offsetX, gesture.offsetY);
            markerLayer.transform.matrix = matrix;

            if ( (gesture.scale != 1 || gesture.rotation != 0) && ( (markerLayer.scaleX < _maxScale && markerLayer.scaleY < _maxScale) || gesture.scale < 1 ) && gesture.scale < 1.4 ) 
            {
                storedScale = gesture.scale;
                // Zoom
                var transformPoint:Point = matrix.transformPoint(markerLayer.globalToLocal(gesture.location));
                matrix.translate(-transformPoint.x, -transformPoint.y);
                matrix.scale(gesture.scale, gesture.scale);
                /**THIS IS WHERE THE CRASH HAPPENS**/
                matrix.translate(transformPoint.x, transformPoint.y);
                markerLayer.transform.matrix = matrix;

            }

}
tvz2xvvm

tvz2xvvm1#

我认为在移动的设备上处理像(9000 x6000)这样的大图像不是一个好主意。我想你正在尝试实现某种Map导航,所以你需要对一些区域进行巨大的缩放。

  • 我的解决方案是将9000 x6000分割成2048 x2048块,然后使用png 2atf实用程序并启用mipmap对其进行压缩。
  • 然后您可以使用Starling轻松加载这些atf图像,并将其添加到stage 3d中,轻松管理它。如果您处理的是9000 x6000图像-您将得到大约15个2048 x2048图像,将它们一次全部添加到舞台上,您可能会认为它会很重,但是mipmap会使内存中只有很小图像缩略图,直到它们没有被缩放--所以当你在放大时不时地从舞台上删除不可见的部分时,并在缩小时将其返回

相关问题