使用旋转和缩放功能将ios7压缩图像固定在画布上

时间:2014-09-30 21:38:57

标签: ios rotation html5-canvas scaling

我遇到使用画布在iOS7中压缩图像的问题。我发现以下帖子似乎正朝着正确的方向发展:

HTML5 Canvas drawImage ratio bug iOS

然而,我不仅仅是绘制图像的简单情况,我还在绘制图像之前旋转和缩放上下文(对于带有EXIF方向数据的缩略图)。代码运行,但我的缩略图中没有图像数据。我猜这与画布旋转和缩放有关。但是,我很难理解为什么当我的挤压系数为1(在没有错误的iOS设备上)缩略图无法正确创建时。

这是我的完整“onload()”代码:

        reader.onloadend = function(evt) {
            console.log('read file data!');
            var tempImg = new Image();
            console.log('created new Image');
            tempImg.src = evt.target.result;
            console.log('set canvas to file');
            // alert(this);
            tempImg.onload = function() {
              console.log('loaded tempImg');
              var MAX_WIDTH = 450;
              var MAX_HEIGHT = 450;
              var tempW = tempImg.width;
              var tempH = tempImg.height;
              if (tempW > tempH) {
                if (tempW > MAX_WIDTH) {
                   tempH *= MAX_WIDTH / tempW;
                   tempW = MAX_WIDTH;
                }
              } else {
                if (tempH > MAX_HEIGHT) {
                   tempW *= MAX_HEIGHT / tempH;
                   tempH = MAX_HEIGHT;
                }
                    }

              var canvas = document.createElement('canvas');
              canvas.width = tempW;
              canvas.height = tempH;
              var ctx = canvas.getContext("2d");
                            // save the current co-ordinate system 
                            // before we screw with it
                            ctx.save(); 

                            // move to the middle of where we want to draw our image
                            ctx.translate(tempW/2, tempH/2);

                if (exifTags.hasOwnProperty('Orientation')) {
                        // EXIF FORMAT: 0x0112  Orientation int16u  IFD0    
                                // 1 = Horizontal (normal) 
                                // 2 = Mirror horizontal 
                                // 3 = Rotate 180 
                                // 4 = Mirror vertical 
                                // 5 = Mirror horizontal and rotate 270 CW 
                                // 6 = Rotate 90 CW 
                                // 7 = Mirror horizontal and rotate 90 CW 
                                // 8 = Rotate 270 CW

                                // Working.  See: http://creativejs.com/2012/01/day-10-drawing-rotated-images-into-canvas/

                  if (exifTags.Orientation == 2) {
                                    console.log('orientation: 2 = Mirror horizontal')
                                    // flip context horizontally
                                    // ctx.translate
                            ctx.scale(-1, 1);
                  } else if (exifTags.Orientation == 3) {
                                    console.log('orientation: 3 = Rotate 180')
                    ctx.rotate(180*Math.PI/180);
                  } else if (exifTags.Orientation == 4) {
                                    console.log('orientation: 4 = Mirror vertical')
                    // flip context vertically
                            ctx.scale(1, -1);
                            } else if (exifTags.Orientation == 5) {
                                    console.log('orientation: Mirror horizontal and rotate 270 CW')
                    // flip context horizontally
                  ctx.rotate(270*Math.PI/180);
                                ctx.scale(-1, 1);
                  } else if (exifTags.Orientation == 6) {
                                    console.log('orientation: Rotate 90 CW')
                    ctx.rotate(90*Math.PI/180);
                  } else if (exifTags.Orientation == 7) {
                                    console.log('orientation: Mirror horizontal and rotate 90 CW')
                  // flip context horizontally
                                ctx.rotate(90*Math.PI/180);
                                ctx.scale(-1, 1);
                  } else if (exifTags.Orientation == 8) {
                                    console.log('orientation: Rotate 270 CW')
                    ctx.rotate(270*Math.PI/180);
                  } else {
                    console.log('unknown orientation: ' + exifTags.Orientation);
                }
              }

              var myImage = this;

              if ($scope.platform == "iOS") {
                 /* Detecting vertical squash in loaded image.
                 * Fixes a bug which squash image vertically while drawing into canvas for some images.
                 * This is a bug in iOS6 devices. This function from https://github.com/stomita/ios-imagefile-megapixel
                 * 
                 */
                function detectVerticalSquash(img) {
                    var iw = img.naturalWidth, ih = img.naturalHeight;
                    var canvas = document.createElement('canvas');
                    canvas.width = 1;
                    canvas.height = ih;
                    var ctx = canvas.getContext('2d');
                    ctx.drawImage(img, 0, 0);
                    var data = ctx.getImageData(0, 0, 1, ih).data;
                    // search image edge pixel position in case it is squashed vertically.
                    var sy = 0;
                    var ey = ih;
                    var py = ih;
                    while (py > sy) {
                        var alpha = data[(py - 1) * 4 + 3];
                        if (alpha === 0) {
                            ey = py;
                        } else {
                            sy = py;
                        }
                        py = (ey + sy) >> 1;
                    }
                    var ratio = (py / ih);
                    return (ratio===0)?1:ratio;
                }

                  /**
                 * A replacement for context.drawImage
                 * (args are for source and destination).
                 */

                function drawImageIOSFix(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) {
                    var vertSquashRatio = detectVerticalSquash(img);
                    console.log('ratio: ' + vertSquashRatio);

                   // Works only if whole image is displayed:
                   // ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio);
                   // The following works correct also when only a part of the image is displayed:
                    ctx.drawImage(img, sx * vertSquashRatio, sy * vertSquashRatio, 
                                       sw * vertSquashRatio, sh * vertSquashRatio, 
                                       dx, dy, dw, dh );                    
                }
                console.log('image to unsquish', myImage);
                // draw it up and to the left by half the width
                // and height of the image 

                drawImageIOSFix(ctx, myImage, -tempW/2, -tempH/2, tempW, tempH);

              } else {
                // draw it up and to the left by half the width
                // and height of the image 
                ctx.drawImage(myImage, -tempW/2, -tempH/2, tempW, tempH);
              }

              // and restore the co-ords to how they were when we began
              ctx.restore(); 
              var dataURL = canvas.toDataURL();
              // alert('created image!');

              var fileName = undefined;

              if ($scope.platform == "iOS") {
                // Store only the name for iOS, hard paths are unreliable

                var timestamp = new Date().getTime();
                fileName = timestamp.toString().concat('t.jpg');
                var thumbPath = fileSystem.root.toURL() + "/STL/" + fileName;
                var thumbName = "/STL/" + fileName;

              } else {

                var name = file.name
                var position = name.length-4 
                fileName = name.substr(0, position) + 't.jpg';
                var thumbPath = fileSystem.root.toURL() + "/.STL/" + thumbName;
                var thumbName = fileName;  
              }


              $scope.mediaCollection.thumbNames.push(thumbName);
              $scope.mediaCollection.thumbPaths.push(thumbPath);
              $scope.mediaCollection.exifData.push(exifTags);
              $scope.mediaCollection.Orientation.push(exifTags.Orientation);

              canvas.toBlob(function(blob){
                console.log(blob.size + ':' + blob.type);                          
                function newFile(fileEntry){
                  console.log('created new fileEntry');
                  fileEntry.createWriter(gotFileWriter, fail);
                }

                function gotFileWriter(writer) {
                  console.log('got fileWriter');
                  writer.seek(0);

                  // window.location = blobUrl;
                  writer.write(blob);
                  console.log('wrote blob!');
                  writeIfReady();
                }

                console.log('about to get Directory');
                console.log('fileSystem root: ', fileSystem.root, $scope.iOS_FS);
                console.log('platform: ', $scope.platform);

                // can replace if/else with single request using $scope.STL_dir
                if ($scope.platform = "iOS") {
                  // May need maintenance... 
                  fileSystem.root.getDirectory('STL', {create: true}, function(dirEntry) {
                    console.log('got directory, about to create thumbnail file: ' + fileName);
                    dirEntry.getFile(fileName, {create: true, exclusive: true}, newFile, fail);
                  }, fail);
                } else {
                  fileSystem.root.getDirectory('.STL', {create: true}, function(dirEntry) {
                    dirEntry.getFile(fileName, {create: true, exclusive: true}, newFile, fail);
                  }, fail);                      
                }

              }, "image/jpg");

            }
          }

0 个答案:

没有答案