在上传之前从Phonegap获取图像的宽度和高度

7
这应该很容易,但我找不到答案。在上传图片到我们的服务器之前,我需要通过Phonegap中的fileURI获取图像的宽度和高度。肯定有一些HTML5/Phonegap的技巧可以在上传之前完成这个操作。以下是一些真正简化的代码,展示了我的进展:
function got_image(image_uri) {
    // Great, we've got the URI
    window.resolveLocalFileSystemURI(image_uri, function(fileEntry) {
        // Great, now we have a fileEntry object.
        // How do we get the image width and height?
    })
}

// Get the image URI using Phonegap
navigator.camera.getPicture(got_image, fail_function, some_settings)

有没有想法这个缺失的部分是什么?我希望我能和Simon MacDonald 或者 Shazron 联系,但是我现在不行。

5个回答

8

以下是一个适当的解决方案。

将图像 URI 传递给此函数。URI 可从 PhoneGap 的 getPicture() 方法中返回。

例如: get_image_size_from_URI(imageURI)

function get_image_size_from_URI(imageURI) {
    // This function is called once an imageURI is rerturned from PhoneGap's camera or gallery function
    window.resolveLocalFileSystemURI(imageURI, function(fileEntry) {
        fileEntry.file(function(fileObject){
            // Create a reader to read the file
            var reader = new FileReader()

            // Create a function to process the file once it's read
            reader.onloadend = function(evt) {
                // Create an image element that we will load the data into
                var image = new Image()
                image.onload = function(evt) {
                    // The image has been loaded and the data is ready
                    var image_width = this.width
                    var image_height = this.height
                    console.log("IMAGE HEIGHT: " + image_height)
                    console.log("IMAGE WIDTH: " + image_width)
                    // We don't need the image element anymore. Get rid of it.
                    image = null
                }
                // Load the read data into the image source. It's base64 data
                image.src = evt.target.result
            }
            // Read from disk the data as base64
            reader.readAsDataURL(fileObject)
        }, function(){
            console.log("There was an error reading or processing this file.")
        })
    })
}

这个答案大部分可以用,但并不完美。在读取图像数据时,我遇到了由于内存问题而导致的间歇性应用程序崩溃。我认为这是因为它正在尝试一次性读取所有数据。如果有人有更好的方法,我会很高兴找到。PhoneGap文档暗示了这个问题:“使用Base64对这些图像进行编码会导致许多较新设备出现内存问题。因此,强烈建议使用FILEURI作为“Camera.destinationType”。”http://docs.phonegap.com/en/2.5.0/cordova_camera_camera.md.html#Camera - Ryan Martin
这不是使用FileURI吗? - Bagusflyer

3
以下代码今天为我解决了同样的问题(在iOS上测试通过):
function got_image(image_uri)
{       
    $('<img src="'+image_uri+'"/>').on('load',function(){
        alert(this.naturalWidth +" "+ this.naturalHeight);
    });
}

希望这能帮到你!

这种方法需要考虑的一点是,在iOS 9 Safari上,自然高度和宽度会混淆。我目前也遇到了这个问题。 - Justin

1
我认为你可以使用getPicture()的目标宽度和高度来限制最大尺寸。 如果需要将它们发送到服务器,我认为服务器代码会帮助获取这些尺寸。 如果你真的需要用js获取这些尺寸,你可以:
var img = new Image;
img.onload = function(){
  myCanvasContext.drawImage(img,0,0);
};
img.src = "data:YOUR_BASE64_DATA";

而且你可以使用 img 来完成


感谢您的回答,但我们不想调整图像大小。即使我们想要调整大小,也没有办法确定源图像的长宽比以正确地进行调整。您的第二个建议没有提供一种从PhoneGap文件对象中获取base64数据的方法。 - Ryan Martin
虽然你已经找到了一种方法,但是你可以将 {destinationType: Camera.DestinationType.DATA_URL} 传递给 getPicture 方法的参数,以获取 base64 数据,而不是获取图像 URI。 - Horst
这真的很好知道。我感谢你的回答。不幸的是,无论是用你的方法还是我的方法处理base64数据,我都会遇到间歇性的应用程序崩溃。Phonegap文档提到了这一点,但我不确定正确的替代方案是什么。“使用Base64对这些图像进行编码已经在许多新设备上引起了内存问题。因此,强烈建议使用FILEURI作为'Camera.destinationType'。” - Ryan Martin
@RyanMartin 如果你想在上传之前在设备上调整大小并保持纵横比,只需在捕获时设置其中一个维度 -- targetWidth/targetHeight -- 为目标大小,然后将另一个设置为非常大的数字(Number.POSITIVE_INFINITY会导致应用程序崩溃)。这将使任何图像(纵向或横向)以原始纵横比适当地缩小。 - danieldkim

0

你可以通过使用Capture API中的MediaFile来实现这一点。

var mediaFile = new MediaFile("myfile.jpg", "/path/to/myfile.jpg");
mediaFile.getFormatData(function(data) {
    console.log("width: " data.width);
    console.log("height: " data.height);
});

应该比当前被接受的解决方案少很多代码。


嗨,西蒙 - 感谢您的回复。不幸的是,这段代码对我似乎不起作用。我目前正在iOS上进行测试,其中该代码始终返回零的宽度和高度。 Shazron在周末提到,他认为在上传之前安全地获取图像的宽度和高度是不可能的,而不会有大量内存消耗。我想我可能会放弃这个尝试,并等待从我的服务器那里得到适当的宽度和高度。虽然这不是理想的情况。 - Ryan Martin
是的,这在Android上可以工作,但在iOS上似乎不行。你可能需要等待服务器的响应。 - Simon MacDonald

0

1.Phonegap提供了一种指定所选图像大小的方法点击此处查看选项

2.如果您需要知道原始大小并且不想指定大小,可以尝试以下代码:

function got_image(image_uri) {
    window.resolveLocalFileSystemURI(image_uri, function(fileEntry) {
       fileEntry.file(function (fileObj) {
                    var fileName = fileObj.fullPath;
                    var originalLogo = new Image();
                    originalLogo.src =fileName;
                    //get the size by: originalLogo.width,originalLogo.height
                });
    })
}

我使用我的方法时遇到了一些内存问题,所以我尝试了你的方法。它总是返回0宽度和高度。你有什么想法吗? - Ryan Martin
Ryan,很抱歉没能及时看到你的反馈。不过,很高兴看到你的解决方案。确实需要一个'onload'来获取新图像对象加载完成后的大小。 - Jack He

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接