Using myDiagram.makeImageData(), the image inside the diagram is lost after downloading as PNG

I have added the below code to download the diagram as a png image. The image icons in the nodes is not displaying. I am implementing this feature in Angular 9. Please let me know if I am missing anything.

public myCallback(blob) {
var url = window.URL.createObjectURL(blob);
var filename = “myBlobFile.png”;

var a = document.createElement("a");
//a.style = "display: none";
a.href = url;
a.download = filename;

// IE 11
if (window.navigator.msSaveBlob !== undefined) {
  window.navigator.msSaveBlob(blob, filename);
  return;
}

document.body.appendChild(a);
requestAnimationFrame(function () {
  a.click();
  window.URL.revokeObjectURL(url);
  document.body.removeChild(a);
});

}

public makeBlob() {
var blob = this.dia.makeImageData({ background: “white”, returnType: “blob”, callback: this.myCallback });
}

That is likely a CORS security problem. Search this forum and the web. For example:
Images do not render in call to makeSvg or makeImage
Using makeImageData() function , the image inside the diagram is lost on Download
https://enable-cors.org/
Allowing cross-origin use of images and canvas - HTML: HyperText Markup Language | MDN

I have checked the above links and added the CORS below code. It did not worked.
sourceCrossOrigin: function(pict) { return “anonymous”; },

Please let me know if any other options.

The primary way the problem is solved is by making sure the images are served with the needed Access-Control-… response headers. enable cross-origin resource sharing

WE have enabled the CORS and still not load the images. Do you have any example of implementing in Angular with PNG download.

What is the URL of your page with the diagram? What is the URL of a failing image in the results of makeImageData?

Are you asking the application URL? The application is not in public domain so can’t share. I am running in my localhost:4200.

I wasn’t asking for access to your app. I was merely asking what domains/host names you are using. So everything is being served from localhost:4200?

What are the headers your server is now sending with each PNG file?

The images are coming from the server http://192.168.90.152:8080/connectall-web/rest/api/adapters/servicenow/servicenow_small.png

Below are the response headers.
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers:X-Requested-With, Content-Type, Authorization, Origin, Accept
Access-Control-Allow-Methods:POST, GET, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin:http://localhost:4200
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Content-Length:703
Content-Type:text/html
Date:Mon, 01 Feb 2021 04:51:37 GMT
Expires:0
Pragma:no-cache
Set-Cookie:JSESSIONID=xxxxxxxxxxxxx; Path=/xxxxxx; HttpOnly
Vary:Origin
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block

I’ll check on the headers tomorrow.

Any reply could be appreciated. Still, I don’t have any clue to get the images in nodes.

Sorry about the delay. I’m not sure what the problem is. When I try it serving my sample app at localhost:5500 and having the Picture.source use the IP v4 address rather than localhost:5500, I found that setting:

        $(go.Picture, "http://192.168.1.152:5500/samples/images/hs1.jpg",
          { sourceCrossOrigin: function(pic) { return "anonymous"; }})

worked well for my test call to Diagram.makeImage.

With that host but without that “anonymous” Picture.sourceCrossOrigin function, the makeImage did not show the image.

I have already added the sourceCrossOrigin and it is not working. Below is my code and we are getting the images dynamically from API.

var adaptertemplate =
(go.Node, "Auto", { locationSpot: go.Spot.TopCenter, isShadowed: true, shadowBlur: 0, shadowOffset: new go.Point(0, 1), shadowColor: "rgba(0, 0, 0, .14)", selectable: true, resizable: false, layerName: "Foreground", cursor: "pointer", selectionAdorned: false, selectionChanged: this.onSelectionChanged }, new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), (go.Shape, “RoundedRectangle”, roundedRectangleParams, {
name: “SHAPE”,
fill: “#fff”,
strokeWidth: 1,
stroke: ‘#f5f5f5’,
portId: “”,
fromLinkable: true,
fromLinkableSelfNode: true,
fromLinkableDuplicates: true,
toLinkable: true,
toLinkableSelfNode: true,
toLinkableDuplicates: true,
cursor: “pointer”,
}),
(go.Picture, { margin: 10, width: this.nodeWitdh, height: this.nodeHeight, cursor: "pointer", **sourceCrossOrigin: function (pict) { return "anonymous"; },** }, new go.Binding("source", "source", this.adapterIcons)), { toolTip: (“ToolTip”, {
“Border.fill”: “#f5f5f5
},

You may need to return "use-credentials" instead of "anonymous" then for the sourceCrossOrigin. Does that allow them to display?

I have used the “use-credentials” in the go.Picture and still facing the same issue. Below is the Blob code

myCallback(blob) {
var url = window.URL.createObjectURL(blob);
var filename = “myBlobFile.png”;

var a = document.createElement("a");
//a.style = "display: none";
a.href = url;
a.download = filename;

// IE 11
if (window.navigator.msSaveBlob !== undefined) {
  window.navigator.msSaveBlob(blob, filename);
  return;
}

document.body.appendChild(a);
requestAnimationFrame(function () {
  a.click();
  window.URL.revokeObjectURL(url);
  document.body.removeChild(a);
});

}

makeBlob() {
var blob = this.dia.makeImageData({ background: “white”, returnType: “blob”, callback: this.myCallback });
}

Hi Walter,

Any reply could be appreciated.

I cannot explain it. As I said, I was unable to reproduce the problem, which probably involves the CORS security issue of your app running at localhost and using resources at the IPv4 address.

I am using the below code to render the images.

$(go.Picture, {
margin: 10,
width: this.nodeWitdh,
height: this.nodeHeight,
cursor: “pointer”,
sourceCrossOrigin: function (pict) { return “use-credentials”; },
},
new go.Binding(“source”, “source”, this.adapterIcons)),

public adapterIcons(source) {
return environment.server.baseUrl + source;
}

Is it possible to see the webpage where this is happening? You can send us email if it’s private, gojs at nwoods.com

Also, are the images actually coming from a different domain? In other words, is localhost actually different from 192.168.90.152 ?

It’s possible that Access-Control-Allow-Origin doesn’t support specifying “localhost”. I don’t know enough about that.

Does the problem not happen when the page is served from the same domain as where the images are coming from?