Uploaded image for project: 'Titanium SDK/CLI'
  1. Titanium SDK/CLI
  2. TIMOB-27108

Android: HTTPClient "responseData" blob returns 0 width/height for images over 512kb

    Details

    • Story Points:
      8

      Description

      Summary:
      When downloading an image file greater than 512 KB via HTTPClient, the resulting "responseData" Blob will return zero "width" and "height". This is not an issue with smaller image files.

      Steps to reproduce:

      1. Acquire an Android device that has Internet access.
      2. Build and run the below code on that Android device.
      3. Tap on the "Download" button.
      4. An alert is displayed indicating that the image blob width/height is 0x0. (This is the bug.)
      5. Notice that the image blob is successfully displayed in an ImageView. Meaning this is only an issue with the "width" and "height" returned by the blob object.

      var imageUrl = "https://jira.appcelerator.org/secure/attachment/66701/NasaMars.png";
       
      var activityIndicator = Ti.UI.createActivityIndicator({
      	indicatorColor: (Ti.App.iOS ? "blue" : "white"),
      	style: Ti.UI.ActivityIndicatorStyle.BIG,
      });
       
      var window = Ti.UI.createWindow({
      	title: "Download Image Test",
      	exitOnClose: false,
      });
      var imageView = Ti.UI.createImageView({
      	autorotate: true,
      	top: 0,
      });
      window.add(imageView);
      var downloadButton = Ti.UI.createButton({
      	title: "Download",
      	bottom: "20dp",
      });
      downloadButton.addEventListener("click", function(e) {
      	var httpClient = Ti.Network.createHTTPClient({
      		onload: function(e) {
      			activityIndicator.hide();
      			downloadButton.enabled = true;
      			var imageBlob = httpClient.responseData;
      			imageView.image = imageBlob;
      			Ti.API.info("@@@ onload() imageBlobSize: " + imageBlob.width + "x" + imageBlob.height);
      			alert("Image Size: " + imageBlob.width + "x" + imageBlob.height);
      		},
      		onerror: function(e) {
      			Ti.API.info("@@@ onerror()");
      			alert("Download Failed");
      			activityIndicator.hide();
      			downloadButton.enabled = true;
      		},
      	});
      	activityIndicator.show();
      	imageView.image = null;
      	downloadButton.enabled = false;
      	httpClient.open("GET", imageUrl);
      	httpClient.setRequestHeader("Accept-Encoding", "identity");
      	httpClient.send();
      });
      window.add(downloadButton);
      window.add(activityIndicator);
      window.open();
      

      Cause:
      When the HTTP response is over 512 KB (Titanium's default max buffer size), then HTTPClient will download the response to a temp file instead of in memory. This bug happens because HTTPClient immediately wraps this temp file with a "responseData" blob before any bytes have been written to it (ie: the temp file is currently empty). This means that the blob will fail to fetch image info. The solution is to re-read the image file's info once HTTPClient finishes the download.

      Work-around:
      In the HTTPClient object's "onload" callback, you can work-around this issue by creating a new blob from the "responseData" blob's file. The new blob will re-read the image file's info now that it has finished downloading.

      var imageBlob = httpClient.responseData;
      if (imageBlob.file) {
      	imageBlob = imageBlob.file.read();
      }
      

        Attachments

          Activity

            People

            • Assignee:
              jquick Joshua Quick
              Reporter:
              rdperottoni Rodolfo Perottoni
              Reviewer:
              Gary Mathews
              Tester:
              Keerthi Mahalingam
            • Watchers:
              9 Start watching this issue

              Dates

              • Created:
                Updated:

                Backbone Issue Sync

                • Backbone Issue Sync is enabled for your project, but we do not have any synchronization info for this issue.

                  Git Source Code