Flex Android 应用程序在使用 jpeg 图像时挂起

发布于 2024-12-23 23:29:11 字数 4248 浏览 1 评论 0原文

我有一个 Flex 应用程序,其中我必须使用 Base64 转换器转换相机拍摄的 jpeg 图片,然后将结果上传到 sqlite 数据库(作为 MEDIUMBLOB)。代码如下所示:

图像的 MXML 声明:

        <s:Group width="480" height="304">
            <s:Label x="0" y="0" width="100%" height="34" backgroundColor="#4D4D4D"
                     color="#FFFFFF" fontSize="30" text="   Select photo" verticalAlign="middle"/>
            <s:Image id="image" x="10" y="42" width="217" height="246" />
            <s:Image id="image2" x="10" y="42" width="217" height="246" source = "@Embed(source='skins/PhotoNotAvailable.jpg')"/>
            <s:Button x="235" y="42" width="235" height="84" label="Take a Picture"
                      click="captureImage(event)" enabled="{CameraUI.isSupported}" fontSize="30"/>
            <s:Button x="235" y="150" width="235" height="70" label="Delete"
                      click="deletePhoto(event)" fontSize="30"/>
        </s:Group>

用于拍照和转换的脚本:

//Taking the pictures

        protected function application1_applicationCompleteHandler(event:FlexEvent):void {
            image.setVisible(true);
            image2.setVisible(false);
            if (CameraUI.isSupported){
                var mediaPromise:MediaPromise;
                camera = new CameraUI();
                camera.addEventListener(MediaEvent.COMPLETE, onComplete);
                camera.addEventListener(ErrorEvent.ERROR, onError);
            } else {
            }
        }

        protected function view1_activateHandler(event:Event):void
        {
            conn  = data as SQLConnection;
        }

        private function captureImage(event:MouseEvent):void {
            camera.launch(MediaType.IMAGE);
        }
        private function onError(event:ErrorEvent):void {
            trace("error has occurred");
        }
        private function onComplete(event:MediaEvent):void {
            var mediaPromise:MediaPromise = event.data;
            image.source = mediaPromise.file.url;
            pictureTaken = true;
        }

//Convertion and uploading to database

protected function AddHandler(event:MouseEvent):void

//irrelevant code skipped

                insertStmt = new SQLStatement();
                insertStmt.sqlConnection = conn;
                var insertSQL:String = ("INSERT INTO RecipeDB (RecipeID, Name, Category, Origin, Recipe, Favorite, Image)" + "VALUES (:RecipeID, :Name, :Category, :Origin, :Recipe, :Favorite, :Image)");
                insertStmt.text = insertSQL;
                    if(pictureTaken)
                {
                    var jencoder:JPEGEncoder = new JPEGEncoder(75);  
                    var imageByteArray:ByteArray = jencoder.encode(image.bitmapData);
                    var baseEncoder:Base64Encoder = new Base64Encoder();
                    baseEncoder.encodeBytes(imageByteArray); 
                    encodedBytes = baseEncoder.toString();
                }
                else
                {
                    var jencoder:JPEGEncoder = new JPEGEncoder(75);  
                    var imageByteArray:ByteArray = jencoder.encode(image2.bitmapData);
                    var baseEncoder:Base64Encoder = new Base64Encoder();
                    baseEncoder.encodeBytes(imageByteArray); 
                    encodedBytes = baseEncoder.toString();

                }
                insertStmt.parameters[":RecipeID"] = ID as int;
                insertStmt.parameters[":Name"] = NameArea.text;
                insertStmt.parameters[":Category"] = TypeArea.text;
                insertStmt.parameters[":Origin"] = OriginArea.text;
                insertStmt.parameters[":Recipe"] = RecipeArea.text;
                insertStmt.parameters[":Favorite"] = 0 as int;
                insertStmt.parameters[":Image"] = encodedBytes;
                insertStmt.execute();
}

//Deleting photo
            protected function deletePhoto(event:MouseEvent):void
        {
            pictureTaken = false;
            image.setVisible(false);
            image2.setVisible(true);
        }

现在,如果没有拍摄照片,程序会正确地将 Skins/PhotoNotAvailable.jpg 上传到数据库,但如果拍摄了照片或拍摄并删除了照片,程序挂起(android询问是否关闭它或等待)。我检查了拍摄照片的大小,它没有超过 MEDIUMBLOB 的大小(图片大约有 2 MB)。可能出什么问题了?

I have a flex application in which I have to convert a jpeg picture taken by camera using base64 converter and then upload the result to sqlite database (as MEDIUMBLOB). The code looks like this:

MXML declarations of images:

        <s:Group width="480" height="304">
            <s:Label x="0" y="0" width="100%" height="34" backgroundColor="#4D4D4D"
                     color="#FFFFFF" fontSize="30" text="   Select photo" verticalAlign="middle"/>
            <s:Image id="image" x="10" y="42" width="217" height="246" />
            <s:Image id="image2" x="10" y="42" width="217" height="246" source = "@Embed(source='skins/PhotoNotAvailable.jpg')"/>
            <s:Button x="235" y="42" width="235" height="84" label="Take a Picture"
                      click="captureImage(event)" enabled="{CameraUI.isSupported}" fontSize="30"/>
            <s:Button x="235" y="150" width="235" height="70" label="Delete"
                      click="deletePhoto(event)" fontSize="30"/>
        </s:Group>

Scripts for taking a picture and convertion:

//Taking the pictures

        protected function application1_applicationCompleteHandler(event:FlexEvent):void {
            image.setVisible(true);
            image2.setVisible(false);
            if (CameraUI.isSupported){
                var mediaPromise:MediaPromise;
                camera = new CameraUI();
                camera.addEventListener(MediaEvent.COMPLETE, onComplete);
                camera.addEventListener(ErrorEvent.ERROR, onError);
            } else {
            }
        }

        protected function view1_activateHandler(event:Event):void
        {
            conn  = data as SQLConnection;
        }

        private function captureImage(event:MouseEvent):void {
            camera.launch(MediaType.IMAGE);
        }
        private function onError(event:ErrorEvent):void {
            trace("error has occurred");
        }
        private function onComplete(event:MediaEvent):void {
            var mediaPromise:MediaPromise = event.data;
            image.source = mediaPromise.file.url;
            pictureTaken = true;
        }

//Convertion and uploading to database

protected function AddHandler(event:MouseEvent):void

//irrelevant code skipped

                insertStmt = new SQLStatement();
                insertStmt.sqlConnection = conn;
                var insertSQL:String = ("INSERT INTO RecipeDB (RecipeID, Name, Category, Origin, Recipe, Favorite, Image)" + "VALUES (:RecipeID, :Name, :Category, :Origin, :Recipe, :Favorite, :Image)");
                insertStmt.text = insertSQL;
                    if(pictureTaken)
                {
                    var jencoder:JPEGEncoder = new JPEGEncoder(75);  
                    var imageByteArray:ByteArray = jencoder.encode(image.bitmapData);
                    var baseEncoder:Base64Encoder = new Base64Encoder();
                    baseEncoder.encodeBytes(imageByteArray); 
                    encodedBytes = baseEncoder.toString();
                }
                else
                {
                    var jencoder:JPEGEncoder = new JPEGEncoder(75);  
                    var imageByteArray:ByteArray = jencoder.encode(image2.bitmapData);
                    var baseEncoder:Base64Encoder = new Base64Encoder();
                    baseEncoder.encodeBytes(imageByteArray); 
                    encodedBytes = baseEncoder.toString();

                }
                insertStmt.parameters[":RecipeID"] = ID as int;
                insertStmt.parameters[":Name"] = NameArea.text;
                insertStmt.parameters[":Category"] = TypeArea.text;
                insertStmt.parameters[":Origin"] = OriginArea.text;
                insertStmt.parameters[":Recipe"] = RecipeArea.text;
                insertStmt.parameters[":Favorite"] = 0 as int;
                insertStmt.parameters[":Image"] = encodedBytes;
                insertStmt.execute();
}

//Deleting photo
            protected function deletePhoto(event:MouseEvent):void
        {
            pictureTaken = false;
            image.setVisible(false);
            image2.setVisible(true);
        }

Now, if no picture was taken, the program uploads skins/PhotoNotAvailable.jpg to the DB correctly, but if the picture was taken or taken and deleted, the program hangs (android asks if to close it or wait). I have checked the size of taken pictures and it does not exceed MEDIUMBLOB`s size (picture has ca. 2 MBytes). What could be wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

咆哮 2024-12-30 23:29:11

从你对所发生情况的描述中我的第一个想法是“断点”。我的手机唯一一次向我显示该消息是当我正在调试并且它在断点处停止太长时间时。

您可以将 event.data 转换为 MediaPromise

    private function onComplete(event:MediaEvent):void {
        var mediaPromise:MediaPromise = event.data as MediaPromise;
        image.source = mediaPromise.file.url;
        pictureTaken = true;
    }

尽管这可能只是一个复制错误。

据我所知,您不需要对图像数据进行 Base64 编码。它已经编码并准备好插入数据库。也许“双重编码”在某种程度上造成了问题。 ???

我会更改

if(pictureTaken)
{
    var jencoder:JPEGEncoder = new JPEGEncoder(75);  
    var imageByteArray:ByteArray = jencoder.encode(image.bitmapData);
    var baseEncoder:Base64Encoder = new Base64Encoder();
    baseEncoder.encodeBytes(imageByteArray); 
    encodedBytes = baseEncoder.toString();
}
else
{
    var jencoder:JPEGEncoder = new JPEGEncoder(75);  
    var imageByteArray:ByteArray = jencoder.encode(image2.bitmapData);
    var baseEncoder:Base64Encoder = new Base64Encoder();
    baseEncoder.encodeBytes(imageByteArray); 
    encodedBytes = baseEncoder.toString();
}

insertStmt.parameters[":RecipeID"] = ID as int;
insertStmt.parameters[":Name"] = NameArea.text;
insertStmt.parameters[":Category"] = TypeArea.text;
insertStmt.parameters[":Origin"] = OriginArea.text;
insertStmt.parameters[":Recipe"] = RecipeArea.text;
insertStmt.parameters[":Favorite"] = 0 as int;
insertStmt.parameters[":Image"] = encodedBytes;
insertStmt.execute();

var jencoder:JPEGEncoder = new JPEGEncoder(75);
var imageByteArray:ByteArray;
if(pictureTaken)
{
    imageByteArray = jencoder.encode(image.bitmapData);
}
else
{
    imageByteArray = jencoder.encode(image2.bitmapData);
}

insertStmt.parameters[":RecipeID"] = ID as int;
insertStmt.parameters[":Name"] = NameArea.text;
insertStmt.parameters[":Category"] = TypeArea.text;
insertStmt.parameters[":Origin"] = OriginArea.text;
insertStmt.parameters[":Recipe"] = RecipeArea.text;
insertStmt.parameters[":Favorite"] = 0 as int;
insertStmt.parameters[":Image"] = imageByteArray;
insertStmt.execute();

“如果出于某种原因您仍然需要 Base64 编码并且它不会产生问题”,我仍然建议像这样重构代码以节省重复,因为两个 if 分支之间唯一不同的是位图的源数据。

var jencoder:JPEGEncoder = new JPEGEncoder(75);  
var imageByteArray:ByteArray;
if(pictureTaken)
{
    imageByteArray = jencoder.encode(image.bitmapData);
}
else
{
    imageByteArray = jencoder.encode(image2.bitmapData);
}
var baseEncoder:Base64Encoder = new Base64Encoder();
baseEncoder.encodeBytes(imageByteArray); 
encodedBytes = baseEncoder.toString();

然而,这只是第一步。一起查看代码会很有用。我假设encodedBytes是一个可供整个类使用的字符串?我看不到如何/何时调用 AddHandler,因此我也无法告诉调用它时的变量状态(这可能与问题有关)。了解 AddHandler 完成后发生的情况也很有用。也许是在挂起的插入语句之后发生的错误?

您调试过它并发现任何错误吗?

我知道这篇文章已经发布了一个月,所以也许你已经明白了。也许你可以分享它,这样其他人就不会犯同样的错误。不管怎样,我希望这可以帮助别人。

My first thought from your description of what happens is "a breakpoint." The only time my phone gives me that message is when I'm debugging and it's stopped on a break point for too long.

You might cast your event.data as MediaPromise

    private function onComplete(event:MediaEvent):void {
        var mediaPromise:MediaPromise = event.data as MediaPromise;
        image.source = mediaPromise.file.url;
        pictureTaken = true;
    }

Though that may just be a copying error.

So far as I can tell you don't need to base64 encode the image data. It's already encoded and ready to be inserted into a database. Perhaps "double-encoding" is somehow creating a problem. ???

I would change

if(pictureTaken)
{
    var jencoder:JPEGEncoder = new JPEGEncoder(75);  
    var imageByteArray:ByteArray = jencoder.encode(image.bitmapData);
    var baseEncoder:Base64Encoder = new Base64Encoder();
    baseEncoder.encodeBytes(imageByteArray); 
    encodedBytes = baseEncoder.toString();
}
else
{
    var jencoder:JPEGEncoder = new JPEGEncoder(75);  
    var imageByteArray:ByteArray = jencoder.encode(image2.bitmapData);
    var baseEncoder:Base64Encoder = new Base64Encoder();
    baseEncoder.encodeBytes(imageByteArray); 
    encodedBytes = baseEncoder.toString();
}

insertStmt.parameters[":RecipeID"] = ID as int;
insertStmt.parameters[":Name"] = NameArea.text;
insertStmt.parameters[":Category"] = TypeArea.text;
insertStmt.parameters[":Origin"] = OriginArea.text;
insertStmt.parameters[":Recipe"] = RecipeArea.text;
insertStmt.parameters[":Favorite"] = 0 as int;
insertStmt.parameters[":Image"] = encodedBytes;
insertStmt.execute();

to

var jencoder:JPEGEncoder = new JPEGEncoder(75);
var imageByteArray:ByteArray;
if(pictureTaken)
{
    imageByteArray = jencoder.encode(image.bitmapData);
}
else
{
    imageByteArray = jencoder.encode(image2.bitmapData);
}

insertStmt.parameters[":RecipeID"] = ID as int;
insertStmt.parameters[":Name"] = NameArea.text;
insertStmt.parameters[":Category"] = TypeArea.text;
insertStmt.parameters[":Origin"] = OriginArea.text;
insertStmt.parameters[":Recipe"] = RecipeArea.text;
insertStmt.parameters[":Favorite"] = 0 as int;
insertStmt.parameters[":Image"] = imageByteArray;
insertStmt.execute();

If for some reason you still want the base64 encoding and it's not creating the problem, I would still suggest refactoring the code like this to save duplication since the only thing that varies between the two if branches is the source of the bitmap data.

var jencoder:JPEGEncoder = new JPEGEncoder(75);  
var imageByteArray:ByteArray;
if(pictureTaken)
{
    imageByteArray = jencoder.encode(image.bitmapData);
}
else
{
    imageByteArray = jencoder.encode(image2.bitmapData);
}
var baseEncoder:Base64Encoder = new Base64Encoder();
baseEncoder.encodeBytes(imageByteArray); 
encodedBytes = baseEncoder.toString();

However, this is just a first stab at it. It would be useful to see the code all together. I'm assuming that encodedBytes is a String available to the whole class? I can't see how/when AddHandler is invoked, so I also can't tell variable states when it is called (which could be related to the problem). It would also be useful to know what's happening after the AddHandler is completed. Perhaps it's an error occurring after the insert statement that is hanging up?

Did you debug it and get any errors to share?

I know the post is a month old, so maybe you already figured it out. Maybe you could share it so others don't make the same mistake. Either way, I hope this can help someone.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文