2


canvas.toDataURL("image/jpg") is working when I'm using an image that is local.
Like this this.originalImage = 'assets/img/defaultImage-900.jpg';

When I change it to a picture from the camera its not working.
Like this this.originalImage = "data:image/jpeg;base64," + imageData;

The error I get in Xcode is
{"code":18,"name":"SecurityError","message":"The operation is insecure.","line":40830,"column":61,"sourceURL":"http://localhost:8080/var/containers/Bundle/Application/4FDE886B-8A64-46AD-8E0C-FDA23C5218CD/Oslo%20Origo.app/www/build/main.js"}

This worked before I updated to iOS 10.3.1... How do i fix?

What I want do to is to merge two images (900x900) on top of each other, to one image.

save() {
//get filter index
this.selectedFilter = this.slides.getActiveIndex();

// run the canvas thing
this.applyFilter(this.filters[this.selectedFilter]).subscribe(() => {
  //done
});
}

Apply the filter on this.originalImage(base64 image from the camera)

applyFilter(filterUrl: string) {
  return Observable.create((observer: any) => {

  let baseImg = new Image();
  let filterImg = new Image();

  let canvas = document.createElement('canvas');
  var ctx = canvas.getContext("2d");

  baseImg.src = this.originalImage;

  baseImg.onload = () => {
    canvas.width = baseImg.width;
    canvas.height = baseImg.height;
    ctx.drawImage(baseImg, 0, 0);

    filterImg.src = filterUrl;

    filterImg.onload = () => {
      let hRatio = canvas.width / filterImg.width;
      let vRatio = canvas.height / filterImg.height;
      let ratio = Math.max(hRatio, vRatio);
      let centerShift_x = (canvas.width - filterImg.width * ratio) / 2;
      let centerShift_y = (canvas.height - filterImg.height * ratio) / 2;
      ctx.drawImage(filterImg, 0, 0, filterImg.width, filterImg.height, centerShift_x, centerShift_y, filterImg.width * ratio, filterImg.height * ratio);


      try{ 
        this.resultImage = canvas.toDataURL("image/jpg");
      } catch (error){
        console.log(error)
      }

      observer.next();
    }
  };

});

}

Camera settings

    // set options
    let options = { 
        quality : 30,
        destinationType : Camera.DestinationType.DATA_URL,
        sourceType : 1,
        allowEdit : true,
        encodingType: Camera.EncodingType.JPEG,
        cameraDirection: Camera.Direction.FRONT,
        correctOrientation: true,
        saveToPhotoAlbum: false,
        targetHeight: 900,
        targetWidth: 900
    };


      Camera.getPicture(options).then((imageData) => {
          this.zone.run(() => {
              this.originalImage = "data:image/jpeg;base64," + imageData;
          });
      }, (err) => {
          if(this.originalImage == null || undefined){
            this.navCtrl.setRoot(SocialTabsPage, { tabIndex: 0 });
          }
      });
  • What do you mean by not working? Can you explain the error that is happening, or give log statements please? – Jacob Boyd Apr 19 '17 at 13:02
  • Xcode is not giving my any form for error... Is just stop running. Everything I console.log before `this.resultImage = canvas.toDataURL("image/jpg");` runs fine. After this line is not running... – Fredrik Hasseleid Apr 19 '17 at 14:32
  • I have no updated the question. Added a try {} function. `The operation is insecure.` – Fredrik Hasseleid Apr 19 '17 at 17:48
  • Are you using a WKWebView to display your canvas? – Jacob Boyd Apr 19 '17 at 18:01
  • Actually, this sounds like a CORS problem(Cross-Origin Resource Sharing)...have you tried saving the image from the camera to the documents Dir. and then pulling the imageData? Also, try `webView.configuration.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")` to help with CORS – Jacob Boyd Apr 19 '17 at 18:07
  • Im not showing the canvas at all. Just trying to post the image data to a web service. Where should I put the code you provided? – Fredrik Hasseleid Apr 19 '17 at 18:30
  • In your viewDidLoad...I had the same security error before, but I was trying to pull a .png of a html5 canvas in a WKWebView...using that code solved my problem, so i'm not sure that is what you will need since you are just trying to upload to a web service – Jacob Boyd Apr 19 '17 at 18:40
  • I have the exact same issue when using canvas.toDataURL where the canvas was loaded with a base64 image that was manipulated in the canvas. BUT only on the first attempt and only on the first (of like 60) base64 image loaded into the canvas. This exact same code worked (and still works) on any IOS prior to 10.3 and also in desktop Safari or Chrome on my mac. – Kerry Davis Apr 25 '17 at 02:45

2 Answers2

3

For future people with a similar issue. In my case, originalImage came from the HTML.

I was getting the same error when its HTML was like this:

<img src="https://example.com/img.jpg" crossorigin="anonymous" ... />

I simply changed the order of the attributes, and the error went away:

<img crossorigin="anonymous" src="https://example.com/img.jpg" ... />
Bart S
  • 1,698
  • 1
  • 16
  • 21
1

I found a solution.

The error I got was The operation is insecure.. And for whatever reason the app did not like that I was using an image from the camera.

So I added baseImg.crossOrigin = 'anonymous'; to the image from the camera and a filterImg.crossOrigin = 'anonymous'; to the filter image.

But this only worked for iOS 10.3 and greater, so I added another if{} function.

Now it looks like this:

  ...

  let baseImg = new Image();
  let filterImg = new Image();

  if (this.platform.is('ios')){
    if (this.platform.version().num > 10.2){
      baseImg.crossOrigin = 'anonymous';
      filterImg.crossOrigin = 'anonymous';
    }
  }
  let canvas = document.createElement('canvas');
  var ctx = canvas.getContext("2d");

  ...
gymate
  • 3
  • 4
  • Setting both baseImg and filterImg to 'anonymous' also works for me. BUT I too had to conditionally test for IOS10.3 as well because setting crossOrigin to 'anonymous' DOES not work /fails in IOS9 – Kerry Davis Apr 25 '17 at 03:58