Whenever I add an image to the canvas on fabric.js then I save and stringify it to JSON in a hidden field the loaded canvas from the JSON data has 0 objects on the console.log and the JSON data in the hidden field / variable is incomplete. The image is inserted and is the only object from the JSON I can edit if I load the JSON data that has been stringified. My program works saving to JSON with adding text, shapes, etc but when I add an image this is what happens.
Here is the code I am using to add the image.
function insertImage(src){
fabric.Image.fromURL(src, function(image) {
var scale = 200 / image.width;
image.set({ left: 40, top: 40, scaleX: scale, scaleY: scale });
canvas.centerObject(image);
canvas.add(image);
canvas.renderAll();
});
}
$( ".image-graphic" ).click(function(){
var imageGraphic = $( this ).attr('src');
insertImage(imageGraphic);
});
Here is the code that runs after that, when it converts it to JSON data in a hidden field.
$( "#testImage" ).click(function(){
var $additionalPropertiesData = canvas.toJSON(['selectable','lockmovementX', 'lockmovementY', 'hasControls', 'hasBorders', 'id']);
$( ".frontData" ).val(JSON.stringify($additionalPropertiesData));
var $frontPreviewData = $( ".frontData" ).val();
});
This is what the JSON data looks like before the image is inserted
{
"objects": [
{
"type": "i-text",
"originX": "center",
"originY": "top",
"left": 544.68,
"top": 144.16,
"width": 307.75,
"height": 65.54,
"fill": "#000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.36,
"scaleY": 1.36,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": true,
"hasControls": true,
"hasBorders": true,
"id": "fullName",
"text": "YOUR NAME",
"fontSize": "50",
"fontWeight": "bold",
"fontFamily": "PT Serif",
"fontStyle": "",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "center",
"textBackgroundColor": "",
"styles": {}
},
{
"type": "i-text",
"originX": "center",
"originY": "top",
"left": 544.68,
"top": 228.48,
"width": 135.85,
"height": 28.84,
"fill": "#000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.36,
"scaleY": 1.36,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": true,
"hasControls": true,
"hasBorders": true,
"id": "jobTitle",
"text": "Your Job Title",
"fontSize": 22,
"fontWeight": "normal",
"fontFamily": "PT Serif",
"fontStyle": "",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "center",
"textBackgroundColor": "",
"styles": {}
},
{
"type": "i-text",
"originX": "left",
"originY": "top",
"left": 45.02,
"top": 472.44,
"width": 109.35,
"height": 20.97,
"fill": "#000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.36,
"scaleY": 1.36,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": true,
"hasControls": true,
"hasBorders": true,
"id": "phoneNumber",
"text": "O:888.888.8888",
"fontSize": "16",
"fontWeight": "normal",
"fontFamily": "PT Serif",
"fontStyle": "italic",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "left",
"textBackgroundColor": "",
"styles": {}
},
{
"type": "i-text",
"originX": "center",
"originY": "top",
"left": 544.68,
"top": 384.88,
"width": 237.27,
"height": 28.84,
"fill": "#000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.36,
"scaleY": 1.36,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": true,
"hasControls": true,
"hasBorders": true,
"id": "companyName",
"text": "COMPANY NAME HERE",
"fontSize": 22,
"fontWeight": "normal",
"fontFamily": "PT Serif",
"fontStyle": "",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "center",
"textBackgroundColor": "",
"styles": {}
},
{
"type": "i-text",
"originX": "left",
"originY": "top",
"left": 461.61,
"top": 436.56,
"width": 122.17,
"height": 18.35,
"fill": "#000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.36,
"scaleY": 1.36,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": true,
"hasControls": true,
"hasBorders": true,
"id": "addressLineOne",
"text": "Company Address 1",
"fontSize": "14",
"fontWeight": "normal",
"fontFamily": "Open Sans",
"fontStyle": "italic",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "left",
"textBackgroundColor": "",
"styles": {}
},
{
"type": "i-text",
"originX": "center",
"originY": "top",
"left": 544.68,
"top": 474.64,
"width": 87.47,
"height": 18.35,
"fill": "#000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.36,
"scaleY": 1.36,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": true,
"hasControls": true,
"hasBorders": true,
"id": "addressLineTwo",
"text": "Address Line 2",
"fontSize": "14",
"fontWeight": "normal",
"fontFamily": "PT Serif",
"fontStyle": "italic",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "center",
"textBackgroundColor": "",
"styles": {}
},
{
"type": "i-text",
"originX": "left",
"originY": "top",
"left": 47.08,
"top": 433.17,
"width": 107.83,
"height": 20.97,
"fill": "#000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.36,
"scaleY": 1.36,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": true,
"hasControls": true,
"hasBorders": true,
"id": "cellNumber",
"text": "C:888.888.8888",
"fontSize": "16",
"fontWeight": "normal",
"fontFamily": "PT Serif",
"fontStyle": "italic",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "left",
"textBackgroundColor": "",
"styles": {}
},
{
"type": "i-text",
"originX": "right",
"originY": "top",
"left": 1044.34,
"top": 433,
"width": 153.52,
"height": 20.97,
"fill": "#000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.36,
"scaleY": 1.36,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": true,
"hasControls": true,
"hasBorders": true,
"id": "emailAddress",
"text": "youremail#email.com",
"fontSize": "16",
"fontWeight": "normal",
"fontFamily": "PT Serif",
"fontStyle": "italic",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "right",
"textBackgroundColor": "",
"styles": {}
},
{
"type": "i-text",
"originX": "right",
"originY": "top",
"left": 1042.98,
"top": 472.44,
"width": 172.43,
"height": 20.97,
"fill": "#000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.36,
"scaleY": 1.36,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": true,
"hasControls": true,
"hasBorders": true,
"id": "webAddress",
"text": "www.websiteaddress.com",
"fontSize": "16",
"fontWeight": "normal",
"fontFamily": "PT Serif",
"fontStyle": "italic",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "right",
"textBackgroundColor": "",
"styles": {}
}
],
"background": "",
"backgroundImage": {
"type": "image",
"originX": "left",
"originY": "top",
"left": 0,
"top": 0,
"width": 1088,
"height": 638,
"fill": "rgb(0,0,0)",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1,
"scaleY": 1,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"src": "/images/sample.jpg",
"filters": [],
"crossOrigin": "",
"alignX": "none",
"alignY": "none",
"meetOrSlice": "meet"
}
}
This is what happens to it after the image is inserted. This JSON data does not load properly and displays the canvas with 0 objects on the console.log.
{
"objects": [
{
"type": "i-text",
"originX": "center",
"originY": "top",
"left": 544.68,
"top": 144.16,
"width": 307.75,
"height": 65.54,
"fill": "#000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.36,
"scaleY": 1.36,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": true,
"hasControls": true,
"hasBorders": true,
"id": "fullName",
"text": "YOUR NAME",
"fontSize": "50",
"fontWeight": "bold",
"fontFamily": "PT Serif",
"fontStyle": "",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "center",
"textBackgroundColor": "",
"styles": {}
},
{
"type": "i-text",
"originX": "center",
"originY": "top",
"left": 544.68,
"top": 228.48,
"width": 135.85,
"height": 28.84,
"fill": "#000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.36,
"scaleY": 1.36,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": true,
"hasControls": true,
"hasBorders": true,
"id": "jobTitle",
"text": "Your Job Title",
"fontSize": 22,
"fontWeight": "normal",
"fontFamily": "PT Serif",
"fontStyle": "",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "center",
"textBackgroundColor": "",
"styles": {}
},
{
"type": "i-text",
"originX": "left",
"originY": "top",
"left": 45.02,
"top": 472.44,
"width": 109.35,
"height": 20.97,
"fill": "#000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.36,
"scaleY": 1.36,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": true,
"hasControls": true,
"hasBorders": true,
"id": "phoneNumber",
"text": "O:888.888.8888",
"fontSize": "16",
"fontWeight": "normal",
"fontFamily": "PT Serif",
"fontStyle": "italic",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "left",
"textBackgroundColor": "",
"styles": {}
},
{
"type": "i-text",
"originX": "center",
"originY": "top",
"left": 544.68,
"top": 384.88,
"width": 237.27,
"height": 28.84,
"fill": "#000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.36,
"scaleY": 1.36,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": true,
"hasControls": true,
"hasBorders": true,
"id": "companyName",
"text": "COMPANY NAME HERE",
"fontSize": 22,
"fontWeight": "normal",
"fontFamily": "PT Serif",
"fontStyle": "",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "center",
"textBackgroundColor": "",
"styles": {}
},
{
"type": "i-text",
"originX": "left",
"originY": "top",
"left": 461.61,
"top": 436.56,
"width": 122.17,
"height": 18.35,
"fill": "#000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.36,
"scaleY": 1.36,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": true,
"hasControls": true,
"hasBorders": true,
"id": "addressLineOne",
"text": "Company Address 1",
"fontSize": "14",
"fontWeight": "normal",
"fontFamily": "Open Sans",
"fontStyle": "italic",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "left",
"textBackgroundColor": "",
"styles": {}
},
{
"type": "i-text",
"originX": "center",
"originY": "top",
"left": 544.68,
"top": 474.64,
"width": 87.47,
"height": 18.35,
"fill": "#000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.36,
"scaleY": 1.36,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": true,
"hasControls": true,
"hasBorders": true,
"id": "addressLineTwo",
"text": "Address Line 2",
"fontSize": "14",
"fontWeight": "normal",
"fontFamily": "PT Serif",
"fontStyle": "italic",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "center",
"textBackgroundColor": "",
"styles": {}
},
{
"type": "i-text",
"originX": "left",
"originY": "top",
"left": 47.08,
"top": 433.17,
"width": 107.83,
"height": 20.97,
"fill": "#000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.36,
"scaleY": 1.36,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": true,
"hasControls": true,
"hasBorders": true,
"id": "cellNumber",
"text": "C:888.888.8888",
"fontSize": "16",
"fontWeight": "normal",
"fontFamily": "PT Serif",
"fontStyle": "italic",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "left",
"textBackgroundColor": "",
"styles": {}
},
{
"type": "i-text",
"originX": "right",
"originY": "top",
"left": 1044.34,
"top": 433,
"width": 153.52,
"height": 20.97,
"fill": "#000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.36,
"scaleY": 1.36,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": true,
"hasControls": true,
"hasBorders": true,
"id": "emailAddress",
"text": "youremail#email.com",
"fontSize": "16",
"fontWeight": "normal",
"fontFamily": "PT Serif",
"fontStyle": "italic",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "right",
"textBackgroundColor": "",
"styles": {}
},
{
"type": "i-text",
"originX": "right",
"originY": "top",
"left": 1042.98,
"top": 472.44,
"width": 172.43,
"height": 20.97,
"fill": "#000",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1.36,
"scaleY": 1.36,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": true,
"hasControls": true,
"hasBorders": true,
"id": "webAddress",
"text": "www.websiteaddress.com",
"fontSize": "16",
"fontWeight": "normal",
"fontFamily": "PT Serif",
"fontStyle": "italic",
"lineHeight": 1.16,
"textDecoration": "",
"textAlign": "right",
"textBackgroundColor": "",
"styles": {}
},
{
"type": "image",
"originX": "left",
"originY": "top",
"left": 300,
"top": 130.27,
"width": 396,
"height": 413,
"fill": "rgb(0,0,0)",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 0.51,
"scaleY": 0.51,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": false,
"hasControls": false,
"hasBorders": false,
"src": "/images/stock/8ball.jpg",
"filters": [],
"crossOrigin": "",
"alignX": "none",
"alignY": "none",
"meetOrSlice": "meet"
}
],
"background": "",
"backgroundImage": {
"type": "image",
"originX": "left",
"originY": "top",
"left": 0,
"top": 0,
"width": 1088,
"height": 638,
"fill": "rgb(0,0,0)",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 1,
"scaleY": 1,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"src": "/images/sample.jpg",
"filters": [],
"crossOrigin": "",
"alignX": "none",
"alignY": "none",
"meetOrSlice": "meet"
}
}
How do you load your json data back?
Try:
canvas.loadFromJSON(json, canvas.renderAll.bind(canvas));
This worked for me.
You need the callback function when you load Images.
My (boiled down) solution looks like
// activepage contains the currently used canvas
this.clickOpenHandler = function(event) {
var file = event.target.files[0];
// file holds now an [file Object]
if (file) {
var reader = new FileReader();
reader.onload = function(e_onload) {
var content = e_onload.target.result;
// content holds now an [object File], like {"objects":[{"type":"rect","originX":"left", ...
activepage.canvas.loadFromJSON(content, function () {
activepage.canvas.renderAll.bind(activepage.canvas);
// Here the canvas already holds the read objects.
console.log(activepage.canvas.getObjects().length); // gives 2 in my testcase
activepage.canvas.renderAll();
$("#pty_open").val(null); // reset input element
});
}
reader.readAsText(file);
}
};
With this HTML input element you can select a local JSON file, which triggers the onchange event:
<input id="pty_open" type="file" />
I hope this example helps you.
PS: Watch out with the onchange event. It triggers only, when the filename is different to the last one. When you select the same file a second time, the onchange does not trigger and nothing happens. I prevented this with the $("#pty_open").val(null); statement.
so something in this json data is breaking it when it is added to the canvas then saved this is the extra json data that is added. Not sure what in there could be causing it.
{
"type": "image",
"originX": "left",
"originY": "top",
"left": 300,
"top": 130.27,
"width": 396,
"height": 413,
"fill": "rgb(0,0,0)",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeLineJoin": "miter",
"strokeMiterLimit": 10,
"scaleX": 0.51,
"scaleY": 0.51,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"clipTo": null,
"backgroundColor": "",
"fillRule": "nonzero",
"globalCompositeOperation": "source-over",
"selectable": true,
"hasControls": true,
"hasBorders": true,
"src": "images/stock/8ball.jpg",
"filters": [],
"crossOrigin": "",
"alignX": "none",
"alignY": "none",
"meetOrSlice": "meet"
}
Sorry for the late answer, I just returned from vacation. And I would have prefered to add a comment, not an answer, but I have too few reputation points.
Back to topic:
The only thing I can imagine is, that the picture does not exist at the given source location ("src": "images/stock/8ball.jpg").