Canvas, disable image download [duplicate] - javascript
This question already has answers here:
Disable to download image from canvas
(4 answers)
Closed 8 years ago.
I'm making a game in html5/js, there is a map with a fog of war on it.
When you right click on the canvas you can save the canvas as an image and so, you can have the whole map in a jpg, but that map need to be hidden.
Is there any trick to disable this ?
I tried to create my fog of war in the same canvas than the map, it works but it's harder to move the fog since i need to create for every move the entire map.
Thank you.
Here’s how to moderately obfuscate your image:
It works by scrambling your map so the casual user cannot easily view it.
Slice your image vertically and horizontally into many pieces.
Scramble all those pieces and create a new scrambled image from them.
Serve that scrambled image to the web page (this scrambled image is unrecognizable to the user).
Save the scrambling order in a JSON array so you can later descramble the image.
Obfuscating Demo: http://jsfiddle.net/m1erickson/wWbt5/
When you need the image, unscramble it into an in-memory canvas that the user can’t see, but which you can programatically use in your game.
De-obfuscating Demo: http://jsfiddle.net/m1erickson/UtN6g/
Code for obfuscating
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; padding:20px;}
#obfuscated{border:1px solid blue;}
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var img=new Image();
img.onload=start;
img.crossOrigin="anonymous";
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/obfuscated.png";
var verticalSlices=60;
var horizontalSlices=60;
var sliceCount=verticalSlices*horizontalSlices;
var sliceWidth,sliceHeight;
var slices=[];
var json;
function start(){
// vars for slice sizes
sliceWidth=img.width/verticalSlices;
sliceHeight=img.height/horizontalSlices;
// create a slices array to be used to scramble our image
for(var i=0;i<sliceCount;i++){ slices.push(i); }
slices=shuffle(slices);
// scramble the original image
var $obfuscatedImage=document.getElementById("obfuscated");
$obfuscatedImage.src=obfuscate(img,slices);
// create a JSON array used to descramble the image
slices.unshift(verticalSlices,horizontalSlices);
json=JSON.stringify(slices);
}
function obfuscate(img,slices){
var tempCanvas=document.createElement("canvas");
var tempCtx=tempCanvas.getContext('2d');
tempCanvas.width=img.width;
tempCanvas.height=img.height;
for(var i=0;i<slices.length;i++){
var s=slices[i];
var row=parseInt(s/verticalSlices);
var col=s-row*verticalSlices;
var x=col*sliceWidth;
var y=row*sliceHeight;
var canvasRow=parseInt(i/verticalSlices);
var canvasCol=i-canvasRow*verticalSlices;
var canvasX=canvasCol*sliceWidth;
var canvasY=canvasRow*sliceHeight;
tempCtx.drawImage(img,
x,y,sliceWidth,sliceHeight,
canvasX,canvasY,sliceWidth,sliceHeight);
}
return(tempCanvas.toDataURL());
}
function shuffle(array) {
var currentIndex = array.length,temporaryValue,randomIndex;
while (0 !== currentIndex) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
}); // end $(function(){});
</script>
</head>
<body>
<p>Before scrambling</p>
<img src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/koolaidman.png"><br>
<p>After scrambling</p>
<img id="obfuscated" width=300 height=300>
</body>
</html>
Code for de-obfuscating
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; padding:20px; }
#obfuscated{border:1px solid red;}
#clarify{margin:10px;}
canvas{border:1px solid blue;}
p{margin:10px;}
</style>
<script>
$(function(){
// this json would be downloaded from the server
// first 2 elements are images width,height
// next 2 elements are #vertical,#horizontal slices
var json="[60,60,734,418,14,393,2863,1779,3555,1208,1300,2715,2380,130,2082,2004,2882,2610,2816,2537,1578,815,571,1188,806,2554,2115,683,923,2049,2180,2429,1799,1185,1827,522,3061,1856,554,1455,1731,3140,831,2022,2983,3203,2350,1586,2320,3494,1946,2628,1424,1900,1027,791,1373,257,3501,1094,1458,3419,2122,858,2515,2312,3521,2795,224,2711,77,2885,1239,2035,1545,1370,2787,468,3579,780,504,2070,2584,1698,2652,898,2111,2305,2901,2929,2482,2193,725,134,2781,2871,2342,2621,2930,3370,169,3107,2695,2862,963,1099,2775,997,2850,1252,2667,1782,1917,61,2645,2788,879,1377,1663,2522,517,2595,166,2815,2510,2835,2538,3551,2011,2942,30,3308,285,2933,1758,2029,2569,220,1105,445,931,2017,153,1728,3407,1057,2163,1636,296,920,2663,995,51,1840,25,1030,3117,1935,840,986,1387,1084,1832,728,37,1551,3361,533,1927,2771,109,3428,2123,2265,277,2643,3587,2764,549,65,785,2943,1643,2453,2467,2906,2335,540,626,3021,1802,2984,1547,284,2125,860,383,2292,2264,350,3141,2670,1722,1440,203,250,2813,1470,1901,2893,1197,2206,3535,2583,1787,1659,1130,541,2524,1435,380,770,161,3038,1607,3257,2240,1175,3176,2750,3304,759,67,993,2964,1497,173,2155,2948,1695,384,472,991,838,1798,977,334,219,2425,2030,269,3206,2423,1925,2202,2099,2721,1087,3508,635,3078,2987,2045,292,3029,2279,2845,2659,2379,492,523,674,1825,887,2169,1328,81,2585,382,2572,2793,1464,3590,453,1134,2067,949,983,1620,2818,6,1820,821,295,1116,2976,544,1913,2562,3406,864,675,2002,967,2985,2710,1784,427,2495,1590,1721,3381,610,3373,3339,1803,1041,2087,1465,1390,1014,1289,1868,2221,1068,2498,183,1680,805,1703,3504,2656,894,1671,2928,3595,825,3068,1053,2109,1292,691,2271,1100,3578,2451,1344,771,3384,2526,692,2336,2037,570,1233,2566,1477,3192,479,3353,1639,1378,3447,2973,3136,2148,588,3042,131,3070,2574,214,2743,3239,1058,1844,1019,3041,656,1893,3193,1902,2065,1449,3470,2608,2655,1708,1374,987,3166,3055,2327,1234,1678,1980,71,807,2228,3033,779,218,1625,405,215,3253,652,3086,1810,1602,1536,2174,2371,1916,2219,3151,410,1683,2442,1195,1141,54,532,3479,1319,733,3365,762,2680,3536,3507,117,1701,68,3148,1904,2782,320,1706,1078,629,2727,3275,649,268,625,885,2796,2660,2358,3177,2962,458,2594,2903,1056,1872,1499,1970,2545,1808,2294,1236,3548,902,3028,2797,3005,1801,3040,3254,1610,2245,2196,695,3322,696,3224,3344,198,901,2431,1657,2323,1486,1874,727,835,355,2322,2356,29,2534,1736,3114,2809,2046,3415,2458,366,3152,2508,2803,1050,2950,2077,409,1525,2108,1073,2939,2470,3489,2722,553,3268,2927,3269,338,3119,1682,477,1543,3238,1841,247,3318,1245,1444,3472,2066,1419,2829,3292,1885,2814,2178,2536,3460,524,1022,1745,2870,3414,2746,196,3534,2765,503,2776,2398,1474,3382,1290,1381,3232,459,1488,1018,63,3317,2159,2491,1186,2246,332,3082,3399,2191,152,828,2755,3106,2034,2484,2044,837,3486,2095,1760,1672,3511,667,737,1270,489,3410,2958,1459,1447,658,2365,1155,406,2000,339,236,560,870,1855,984,1386,158,1230,1170,1184,3226,1190,2063,1986,3185,1365,1988,457,1069,1472,699,959,682,3374,665,1329,1891,331,713,1923,3325,133,801,1366,1354,1569,2362,1272,2587,2926,814,755,768,883,1691,3334,604,2657,1985,636,434,412,2133,3503,3433,359,3319,498,2786,1198,1015,596,2521,1003,443,1000,231,154,2306,1253,86,3490,347,2532,3385,341,1220,2339,115,221,2303,3455,87,2089,2837,1786,973,5,3026,2003,1582,3309,2623,1293,2644,439,2101,681,2579,2205,2907,992,2284,487,1035,3050,841,969,1127,786,2898,1807,1759,1392,563,2661,2839,1738,1911,2598,1598,1751,1132,2079,243,2844,2401,2434,2461,1644,1775,1107,619,2249,2040,2578,738,547,1343,1400,53,1221,1043,1651,140,3024,1737,3518,3421,3549,1360,1081,3083,2773,1243,3337,888,631,1023,240,505,416,2728,2188,904,1550,2696,2647,1984,72,2406,108,606,2481,3444,1249,804,2996,3388,2410,1850,1158,3454,3506,1238,2236,589,1422,1847,2293,2724,3347,1567,3483,2812,849,899,941,2462,2091,537,2012,632,543,594,1306,132,546,1060,2223,3516,1697,816,3345,2145,1848,436,2671,155,1889,2048,2262,3559,3532,138,1299,2020,1957,2974,1715,643,3487,1317,2714,2162,1355,1067,926,732,1924,2783,1712,2636,3393,3112,2672,3499,2998,1726,3517,1594,3378,494,2059,1282,372,3313,0,1217,469,47,2445,1573,3459,2673,2273,249,2924,3529,2653,1397,2993,2506,810,2033,1049,2607,736,3429,1498,3403,162,265,1036,297,2260,3163,2447,659,2408,1148,146,1336,2678,3002,3048,288,1382,1597,1596,1969,1313,1681,35,1570,1445,3289,1363,2693,1561,3446,988,1968,2274,426,317,151,2945,435,283,3213,2697,1304,915,2332,3488,1987,3052,3411,1599,2509,1884,2730,2143,2444,2965,209,2131,2217,597,2438,2717,2593,1476,874,1714,844,471,1711,2076,2861,730,2698,2136,1965,3044,2914,2010,395,2396,342,176,2208,404,2254,702,2860,1656,3387,1906,3165,2549,1990,402,2421,233,2977,1260,3181,668,1140,177,3510,2051,1244,1818,2119,276,1858,2807,1146,739,1725,689,1092,1205,62,1646,1061,2552,21,69,2347,2649,3074,763,3266,1291,2539,1592,2126,2156,85,1314,124,1413,1574,2859,2798,1418,255,262,3231,1534,2307,2602,3496,1066,703,129,990,976,3121,293,3178,2016,3586,1664,690,3564,3214,2664,2235,2469,1839,1468,1817,2688,3364,2519,1266,2075,280,2142,1052,1806,3468,3354,1204,2875,2616,2542,2426,462,767,1504,1967,186,1031,139,2455,1296,2094,748,181,3098,2369,962,3283,160,2770,2085,608,2681,637,1608,2684,1909,2194,333,421,1380,542,3270,502,3375,3088,3102,163,1702,1849,3079,241,2800,3592,2856,1614,2441,2792,362,3219,1833,1187,871,839,2904,377,2256,1177,1966,1432,407,223,3199,1750,3130,2128,3563,1995,3227,851,2955,1091,1206,1631,796,1804,1202,758,2517,892,583,534,3583,1405,2280,2096,996,707,2392,44,2233,708,1136,2646,2551,687,797,1108,1013,345,1478,206,3440,1615,2309,1042,3157,1368,414,1796,2211,2505,371,3366,2734,3204,1974,303,99,306,2622,1326,2759,3527,3060,1978,335,1516,3515,456,1025,2784,1944,1364,84,2824,1951,3331,2269,3229,440,3047,1527,2889,721,475,107,1033,1286,3442,290,1420,1649,1743,2563,2507,2560,447,2113,302,3105,394,1193,2995,793,1515,1753,1151,1961,776,3552,1934,3560,520,3127,2285,2372,1268,526,1626,2921,2573,2525,1017,679,2165,488,575,1992,2872,1182,3222,2118,200,2605,2344,3149,2780,2514,38,3343,2036,1757,2104,2489,2527,924,830,3260,2141,1879,2090,189,1425,968,323,45,2757,91,3402,1149,2544,907,519,3228,3320,2283,1189,3252,3296,929,98,2638,3473,1788,1568,254,1676,3377,803,2112,3565,650,1150,3220,389,159,3197,2922,777,1448,513,3108,2880,677,630,3174,1780,1496,1414,1771,2580,2114,3383,2363,1080,1345,1214,386,180,267,3427,1996,216,829,3333,1226,433,1399,551,1852,3543,1032,3080,1137,446,856,743,2502,211,3072,2042,2978,2589,896,1145,357,572,2459,18,424,1029,1218,611,2247,3312,3004,275,1938,2706,2951,2504,914,535,3264,3430,530,3567,697,2400,1886,3233,3056,2952,1932,2940,301,2762,3135,882,184,704,460,3404,1274,1859,419,3537,2319,126,210,2716,1223,1873,1383,2881,1687,2377,64,3299,2234,3371,2259,3491,2548,3216,3288,2864,2902,2412,1020,1789,1960,309,1822,989,3420,246,3550,94,3208,391,3066,694,567,2637,3110,3316,2232,1265,1878,1686,179,940,1231,197,2097,3310,1560,1555,1085,820,2308,1617,2739,1724,1371,1950,2994,1860,2912,745,2760,2842,1353,116,1929,2026,586,2740,644,654,222,1861,43,698,360,1410,1242,2752,2272,2954,516,2105,3011,2449,432,827,593,1263,2794,685,1521,672,1595,2050,282,1823,1907,2869,1532,964,1542,614,2361,673,1275,1295,1585,1423,370,194,1653,934,3327,3525,935,2375,500,978,1871,753,1143,2625,2226,2464,3512,686,3360,2250,2949,3104,859,3417,579,1501,788,3462,1310,2516,1369,2997,1830,2528,2705,576,1393,1097,1843,3568,2386,1979,3054,142,3432,11,1408,834,167,3182,919,2513,1565,2543,1396,289,846,3071,2190,2634,2890,1654,308,798,385,3300,847,2541,2222,1972,1064,3363,2183,1717,3392,1704,1997,3025,2330,2383,1046,510,3505,506,75,2189,59,234,2149,1908,425,1460,1763,917,1732,3037,2957,600,73,2021,639,4,2853,2956,1228,581,235,2577,897,3241,1010,3096,1669,2446,843,2744,1006,1247,298,318,590,1790,356,3556,2291,2052,455,950,928,2758,1748,832,558,1642,2735,373,1429,3195,3261,2774,1494,2564,3175,2990,3293,2820,2150,710,648,483,792,281,112,932,688,740,3009,980,2873,1120,884,1735,2936,1926,1919,1028,2296,528,826,2650,495,143,1710,3546,1142,1628,2238,1342,2691,1070,1538,1037,765,2738,3146,3243,582,1931,192,3031,1503,3596,340,1461,3582,3443,1021,592,2268,1240,947,3089,103,3425,1510,605,2328,2887,2171,1495,2062,187,1083,1835,1869,1674,2834,316,1616,664,3513,2290,3408,1887,2501,1153,263,1059,213,274,2179,1684,1766,878,1427,3523,3207,3187,165,3035,1943,56,1215,2354,2316,2699,1606,312,3372,2935,2821,105,2198,313,3217,2346,1385,1320,624,3201,607,819,1008,3120,2100,2364,1200,3557,2028,1635,701,1809,3014,2685,2486,2209,1795,128,3533,1707,2215,2353,1566,2281,2941,2687,3581,2056,3321,2960,3542,2025,2700,60,1584,1857,662,1696,3302,2008,2001,2999,2895,2415,3018,367,2253,1918,3113,1755,199,974,1912,1685,1655,775,2005,2405,239,3476,408,1530,444,756,813,2590,2499,2018,122,1211,365,2606,3013,3391,2060,430,1350,1783,3409,55,3158,259,811,1005,1248,188,794,1009,2391,42,19,3094,1739,1524,3368,817,3223,2015,324,1580,651,3335,1101,550,1241,2586,3524,812,1442,2753,3395,2480,1279,1824,1854,1553,464,1508,3099,1764,32,2175,1159,1256,481,3457,40,2258,3156,1587,1312,1109,2614,1890,3520,3526,3294,1229,2846,913,2243,2763,3190,2475,3036,2676,655,1002,952,3179,90,862,1630,319,2761,569,2531,1216,2932,17,2503,800,1601,3458,1308,1398,2210,754,2822,3186,1139,1791,1446,2098,1727,33,3336,387,2106,773,229,2629,1430,1668,3423,1777,2134,8,2843,2959,2966,1993,3017,2944,2666,508,3142,2511,3445,1451,938,3531,1471,865,3281,1409,2785,343,2874,1812,195,2443,2799,2823,1040,1624,1981,1939,2277,633,2195,48,1280,3019,2212,562,1883,3084,2754,3144,3356,2988,2729,2014,3092,3218,1894,1352,1881,2876,2185,353,3541,2737,3032,1104,354,272,304,66,521,3075,1741,125,1358,3405,3237,2231,3128,3528,726,2418,2278,3295,2298,2474,3451,2244,3064,12,1514,2867,1255,2806,2064,2216,2384,1115,201,411,3398,2747,975,82,3571,930,1431,1112,212,1834,599,2310,909,615,620,1346,1641,1752,3396,1761,906,718,1517,2313,2550,3477,2349,2337,328,2257,2953,1562,463,2027,2092,2239,1039,363,757,536,149,1716,1746,3129,2603,1088,1914,1942,1920,135,2170,706,3150,2991,3081,305,1921,3389,1133,886,2352,2896,1123,2766,2838,670,2255,958,2261,653,2512,1571,1401,2397,869,2967,3180,1520,1165,3154,13,921,1619,3262,774,1492,2810,1126,1540,3173,2424,3212,1340,2732,2640,2329,2718,912,548,2289,2769,2225,3593,3562,2242,641,3251,1774,1507,3561,557,2600,1335,3452,999,2200,1307,722,2385,3573,512,1347,1880,465,3340,1324,480,3397,1947,1489,939,2229,2132,2472,2615,3030,2378,617,1537,2460,2970,484,2227,908,3509,256,3171,2620,1160,2493,2127,315,2428,731,3122,1318,127,3456,3111,242,1191,1095,2751,1899,781,3514,1800,3413,2868,556,2897,1453,3500,1167,2547,2686,2158,417,3100,2124,3126,2057,3067,3095,1544,1634,3589,2963,3475,1456,2341,3247,3244,193,1176,1034,2571,3077,174,2355,1793,1161,3230,1156,2043,3161,1232,2931,3282,1213,119,2858,2479,2971,1093,57,1720,1756,482,2599,2852,337,3278,93,2731,1278,1618,1379,1679,848,497,1327,1166,2402,3245,1235,1637,1331,3118,3301,3390,2009,3519,1152,1838,1563,3449,3478,1183,3349,2961,1341,3467,2448,1439,3277,3352,2888,397,486,2662,2144,1518,751,2604,2690,714,299,3246,172,2172,1945,2302,3545,2778,27,1633,2866,2567,2854,1315,3159,741,1867,118,442,120,2749,2918,3012,2989,352,1124,145,1322,660,618,1225,31,1281,876,943,3341,1949,1001,861,1103,2836,1846,2184,2613,3437,2492,1533,1754,3191,110,3324,2849,2490,3291,3093,3287,2756,3139,1044,1224,2708,2478,1194,1388,3039,3438,364,609,3234,3279,3290,3553,1482,3436,1851,228,3020,2237,1539,2840,1303,1403,2588,1956,2617,3285,1391,2768,2177,1121,1250,971,3001,2083,1958,1402,1837,2831,2910,1473,3394,1826,1487,1237,245,1273,2207,822,49,953,782,399,552,1119,3085,1321,1892,428,1222,1467,2427,2597,1842,3027,3103,1588,1209,3065,2630,3116,1147,783,3087,3584,2160,237,390,3357,1259,2833,1792,1576,3485,2804,2435,538,1948,136,1098,2468,501,1012,3131,3376,168,853,1660,2972,529,202,1629,2376,3284,711,420,3069,866,3,3265,2315,1662,602,1898,2203,438,2031,3259,3386,3539,2192,1558,1433,1438,1173,2683,1074,1375,1122,351,2382,2665,329,2032,16,1575,2674,3591,3298,616,1129,944,2791,1814,555,717,2825,346,545,2023,2618,3057,2287,875,1316,2168,1897,3062,647,1111,392,83,1667,3401,1484,1062,1666,1700,880,2321,1079,3481,2635,1862,3205,2173,89,2387,2072,248,1131,1048,3424,1169,584,2357,3492,2393,3000,3585,3091,836,833,1276,7,966,190,1125,2404,123,2317,1816,369,3314,2805,2137,927,2399,2071,1954,661,1600,1928,3183,1277,2633,2592,1729,1251,2340,1876,628,401,1612,2624,2969,561,872,1661,752,1593,2324,2161,595,693,3273,1463,1180,1579,1529,2186,2726,3271,720,750,2851,933,3023,2601,2982,1411,2288,1933,2692,1941,700,3015,2345,2947,1264,121,141,2556,2120,719,2409,2440,577,448,603,1246,1485,3169,3016,1577,2359,207,1016,2078,2916,2038,291,1513,70,2301,705,1797,2886,2024,2394,1457,2654,2934,2456,2197,3125,2351,646,2865,2039,2658,2373,3090,799,3097,2166,1936,114,3577,678,3572,1767,2553,2923,2827,2500,621,2979,2454,2847,585,2980,937,769,3249,3569,2925,1287,784,2789,893,1096,2367,2102,1407,2086,809,3184,881,2167,330,1971,1778,3359,3346,2275,954,3530,645,2748,1613,1940,1903,2801,2333,910,1367,1953,2187,3123,2299,2414,2214,936,2152,3200,3358,1583,3101,1301,2463,1977,1718,3580,1813,2381,965,3034,877,2055,1603,2709,1416,3576,226,1535,2619,922,1384,3422,2436,3155,1528,1658,3297,1768,3196,1437,78,790,1026,2248,1853,3426,1434,747,2477,3305,2533,2295,3453,2675,1421,1011,2325,1311,3272,1611,2297,1552,1689,461,449,2736,956,2857,3469,3006,787,657,92,3172,3342,527,217,1297,2596,2992,1910,850,15,1,2314,2520,2892,2088,3380,2213,3330,9,287,3276,3326,310,400,1284,1404,178,2819,749,1082,1922,3493,3463,1271,2848,1483,863,2061,3497,942,985,2631,574,1794,1086,204,2331,244,1212,1475,422,573,3441,104,566,634,97,1135,2390,205,1323,3188,1955,423,41,1436,2366,981,273,666,171,3306,1509,3362,2570,1359,2103,1983,2334,2832,845,2006,1522,2712,1866,3209,2703,1332,52,1412,873,1339,1075,1045,22,3147,3058,2266,1815,150,3124,378,3597,1334,191,322,1719,1179,2286,321,258,1090,1454,2891,2627,1181,1203,314,1531,1749,474,1462,311,2130,1877,39,3109,1744,2074,3221,3307,2450,2841,1976,2007,2884,3482,2073,1007,2485,684,2487,185,1638,1690,80,1652,175,2466,2407,1650,957,2081,2720,2612,451,1875,3225,3598,478,948,1937,490,824,868,358,1962,2968,2981,2154,1362,3133,466,2121,945,1994,2779,2557,2611,325,2725,3435,2915,2370,1915,2138,3202,1267,1819,1443,2058,1077,2181,2304,1773,1071,2374,1288,627,2591,715,111,3594,3168,3007,2555,3003,476,1785,1895,260,336,2439,709,766,1210,772,916,671,1675,467,3143,3137,2182,1227,1452,2348,2053,1394,587,1257,1554,101,3329,1376,1609,2641,2911,1357,1441,398,1479,1038,3063,2201,2080,2609,2420,2719,2360,3544,182,2668,925,2,327,271,1258,2224,2937,1480,2559,2437,3484,3132,1178,998,3369,3242,2494,266,96,2772,2252,3049,1219,34,1709,2877,3461,3022,1110,2855,1171,960,403,1964,890,1905,2777,1623,2395,3043,137,1930,3051,2069,3348,2338,1677,1648,3211,1742,1294,1556,746,415,1772,3502,1113,3498,2054,994,3400,1762,1734,441,3236,1076,2430,58,50,1506,1673,36,1469,1559,2117,3073,2452,156,1828,3465,3053,3566,2639,1500,344,1262,1428,1254,1157,1557,1163,1870,3547,431,493,1882,1694,2241,3522,2701,3194,1776,2311,2518,2084,539,1349,3045,452,1298,2389,2626,663,742,2689,955,1831,23,979,1836,642,1581,3323,509,716,429,1426,496,1589,1888,591,3540,348,157,1333,764,802,1963,2476,2733,1269,1283,413,1999,2568,1692,867,1829,559,106,2135,3554,2019,3418,2808,3570,28,2826,2648,1505,454,2047,2632,1647,2417,1481,3059,2107,1330,1138,1491,2679,905,2218,1896,1199,564,2811,1406,1564,450,3153,2270,680,2068,951,601,1054,808,2830,1548,1765,3170,113,3367,2116,565,2326,3160,2497,1730,88,1863,2878,1989,24,375,294,278,2529,2013,1781,232,1733,2742,580,2457,3332,26,1490,3115,1309,1065,598,3351,1770,3466,970,1395,1821,3350,3167,514,735,3046,3255,2905,1348,1172,1747,2920,147,2471,1769,2790,2139,2041,20,1952,891,2300,795,1864,1285,613,2176,638,2388,1196,1622,2473,676,612,2582,623,1811,2416,1670,396,2413,1356,1572,74,2157,3558,2411,3338,2707,2682,2110,2318,1337,918,2561,1519,1705,669,2164,1351,1604,2432,3416,1207,982,1665,2151,1063,3138,1523,2713,3235,1024,3575,972,2642,2879,3448,3495,3328,1982,2530,1627,1959,744,3240,3434,2129,1805,1723,1417,3280,2723,1493,2894,1713,76,900,2975,2433,854,10,760,100,3355,568,2546,1089,2147,2909,789,531,1415,46,307,3480,507,3164,2677,2419,3189,622,895,2488,2704,1174,3471,2465,1975,485,3248,3379,300,279,3474,1688,1192,170,286,2986,903,3303,3263,1128,2220,712,3315,2828,1621,1144,2343,491,2565,1305,578,729,3076,251,2483,1302,2767,818,3574,1164,2919,2946,1640,3267,525,1526,961,1004,857,2576,2917,470,2913,437,2496,723,144,1973,3210,2368,2282,2741,2651,2694,1512,2263,518,1605,381,3008,1201,95,225,2899,761,1699,368,1632,2251,2745,1502,3134,1991,640,1072,349,1511,1102,778,2802,852,388,1338,1051,1740,3450,1325,1114,1162,2153,2276,1845,3439,227,3464,3588,1549,252,2908,2669,2204,3286,1372,2540,2883,2523,3145,2146,946,1047,326,2558,238,724,889,3250,230,823,1154,2140,2199,1450,2575,511,1106,499,1361,1118,1389,3599,270,3538,3010,3256,253,2900,911,1865,102,515,1261,3311,3162,2093,1117,3431,264,3412,361,2230,2817,2403,208,3198,1693,1998,3274,2938,2267,473,3258,1055,842,2581,1541,148,2422,164,2702,379,79,1168,3215,1546,2535,1645,1466,261,855,1591,376,374]";
var keys=JSON.parse(json);
$button=document.getElementById("clarify");
$button.style.display="none";
var img=new Image();
img.onload=function(){
$button.style.display="block";
}
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/obfuscated.png";
function deobfuscate(obfuscatedImage,keys){
var tempCanvas=document.createElement("canvas");
var tempCtx=tempCanvas.getContext('2d');
tempCanvas.width=obfuscatedImage.width;
tempCanvas.height=obfuscatedImage.height;
var verticalSlices=keys.shift();
var horizontalSlices=keys.shift();
var sliceWidth=tempCanvas.width/verticalSlices;
var sliceHeight=tempCanvas.height/horizontalSlices;
for(var i=0;i<keys.length;i++){
var s=keys[i];
var row=parseInt(s/verticalSlices);
var col=s-row*verticalSlices;
var x=col*sliceWidth;
var y=row*sliceHeight;
var canvasRow=parseInt(i/verticalSlices);
var canvasCol=i-canvasRow*verticalSlices;
var canvasX=canvasCol*sliceWidth;
var canvasY=canvasRow*sliceHeight;
tempCtx.drawImage(obfuscatedImage,
canvasX,canvasY,sliceWidth,sliceHeight,
x,y,sliceWidth,sliceHeight);
}
return(tempCanvas);
}
$("#clarify").click(function(){
var canvas=deobfuscate(img,keys);
document.body.appendChild(canvas);
});
}); // end $(function(){});
</script>
</head>
<body>
<button id="clarify">De-obfuscate</button>
<p>The obfuscated image</p>
<img id="obfuscated" src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/obfuscated.png">
<p>The de-obfuscated canvas</p><br>
</body>
</html>
This code may help:
document.body.addEventListener('contextmenu', function(e) {
e.preventDefault();
});
This will disable context menu on a page. Instead of document.body you can write your canvas element:
document.getElementById('map_element').addEventListener('contextmenu', function(e) {
e.preventDefault();
});
where map_element is ID of the canvas element
UPDATE:
but even this protection might be broken by executing in browser console:
document.getElementById('map_element').toDataURL('image/jpeg');
I think the right decision is to download from server small regions of the map part by part
The first and the very simple way of doing that, would be the usage of HTML5
element {
background-image: url('../link/to_image.png');
}
Which won't be saved if the user right-clicks the image and clicks Save Image as...But still remember that the user can get the image from Inspector!
This way, the image won't be saved through right click atleast! And your map will be saved.
Second method is to use return of JS and stopping the event from occuring.
$('img').mousedown(function (e) { // mouse down on the image
if(e.button == '2') { // if right click
return false; // return nothing! :)
}
}
This is the easy way, since you won't be require to update the background-image everytime! But, use what you like! :)
No, there is no way you can prevent a user from saving what is already been downloaded to the browser.
You can make it "harder" for the user by adding a div on top over your canvas element and set its background to the image (or if possible just apply a css background to the canvas element itself).
You can disable the context menu as mentioned in another answer but the user can override this or use a browser that doesn't care (not sure if Opera has fixed this at the moment..).
You can also generate a bunch of layers and split your map file into many tiles, download those to the browser and draw a tile on separate layers. This is more complicated and makes it a bit more boring for the user to have to download all tiles and stitch them together.
But conclusively, no you can't prevent this - the user only need to go to console and network to find the downloaded image and save it out to the disk.
Related
compare 2 canvas elements for similarity and return result
I'm new to js and html5 so here's what I'm doing : I'm working on a game that helps in teaching illustrator shortcuts, the firts level consist of 2 canvas one with an already existing image and the other blank and ready for user to draw on, on ctrl + s press(sure I disabled it's default action using jquery) I want to compare the content of those 2 canvas elements. I've found Image similarity api from deepai.org very useful and accurate, but it only accepts url or input="file" content, so I'm trying to find a way to upload (maybe) the drawn canvas as an image to a server and get the url like this : https://server.com/myaccount/images/img1.png and since i only upload one image I can pass that static url to the api in addition to the original image which will also have a static url so hopefully it compares.
I made a solution that works without a server. But I couldn't make it work in an online code repo like jsfiddle. So I put it on my own server for you to check. http://paulyro.com/paul/deepai/ For convenience I put everything in one file. Of course it would make sense to save the JS in a separate file. But I let that up to you. For explanation: the red square in a black frame is the canvas. I generate two images and add them to the page. Then I send those images to the deepAI server when you press the button. You will only need one generated img, but for testing purpose I made 2. Let me know if this is what you were looking for. Of course I expect you to adapt this solution to your exact needs ;) This is the code: <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>DeepAiDemo</title> <script src="https://cdnjs.deepai.org/deepai.min.js"></script> <style rel="stylesheet"> canvas { border: 1px solid black; } </style> </head> <body> <canvas id="canvas1" width="200" height="200"></canvas> <button name="button" onClick="load()">Press me</button> <div style="position:absolute;left:400px; top:30px; height: 354px;" id="messages">Result will get here</div> <script type="text/javascript"> (async function() { var can = document.getElementById('canvas1'); var ctx = can.getContext('2d'); // create green canvas and make it an image ctx.fillStyle = "green"; ctx.fillRect(75, 75, 50, 50); var img = new Image(); img.src = can.toDataURL(); document.body.appendChild(img); // create red canvas and make it an image ctx.fillStyle = "red"; ctx.fillRect(75, 75, 50, 50); var img2 = new Image(); img2.src = can.toDataURL(); document.body.appendChild(img2); })() const load = async () => { document.getElementById('messages').innerHTML = "Waitng for response..."; deepai.setApiKey('xxxxxxxxxxxxxx'); var images = document.getElementsByTagName('img'); console.log("amount images: "+images.length); console.log(images[0]); console.log(images[1]); var resp = await deepai.callStandardApi("image-similarity", { image1: images[0], image2: images[1], }); console.log("response: "); console.log(resp); document.getElementById('messages').innerHTML = "Distance: " + resp.output.distance; //resp.output.distance contains the number from the server. }; </script> </body> </html> Cheers, Paul
While Removing div using javascript, the backgroundimage stayed
I am having a problem with the background-image inside a div. I am trying to program a html-webgame, using mainly canvas. So as a result, my index looks like this. <head> <title>Cardgame</title> <link rel="stylesheet" type="text/css" href="resoursces/css/index.css"> </head> <body> <div class='game_object' id='game_object'> <canvas class='main_canvas' id='main_canvas'>Error</canvas> </div> <script type="text/javascript" src='main.js'></script> </body> The problem comes along like this: window.onload = (function() { window.addEventListener('resize', resizeCanvas, false); function resizeCanvas() { drawing(); } resizeCanvas(); })(); in the function "drawing()" i am doing 2 things. The first one is to remove all divs, i have created so far, and the second is the i am drawing all div's new with new x-coordinate, y-coordinat, hight and width. So it looks like this function drawing() { delete_div(); create_div(); } function delete_div() { battlefield_div.style.removeAttribute("backgroundImage", false); battlefield_div.parentNode.removeChild(battlefield_div); } funtciont create_div() { var board_div= document.createElement("div"); board_div.setAttribute("id", "board"); board_div.style.position = 'absolute'; board_div.style.top = board.y1+"px"; board_div.style.left = board.x2+"px"; board_div.style.height = board.y2 - board.y1+"px"; board_div.style.width = board.x1 - board.x2+"px"; board_div.style.zIndex = '2'; board_div.style.backgroundImage="url(resoursces/images/board.png)"; board_div.style.backgroundSize = "100% 100%"; game_object.appendChild(board_div); } This game is a cardgame and i wanted to make it to resize when ever you change the height and the width of the browser without loosing its function. The divs i am creating are part of the functionality. Everything works fine with it, except one thing: Whenever you resice the browser, the divs are getting remove and new ones are calculated but the background-images is still there. So when you resized your browser like 4 times, you are just seeing the background-images. What am i doing wrong? Can anyone help me?
jQuery/Javascript: Button - replaces images
I have little knowledge of JavaScript and need some help. I have this code (below) which when the countdown finishes, it replaces the image with a new one. I wanted to modify this so that instead of a countdown - a button (img) is pressed instead. Here's my design to get an idea: Design. I'm guessing I'll need 4 imageloaders instead of just one this time (one for each box) and some code to make it so that when the "older ->" button is clicked it triggers the loading of images? <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js" type="text/javascript" charset="UTF-8"></script> <script src="js/jquery.countdown.js" type="text/javascript" charset="UTF-8"></script> <script type="text/javascript"> <!-- The ready() function will force the browser to run wait running the javascript until the entire page has loaded --> $(document).ready(function() { // The jquery code for constructing and starting the counter // has been wrapped inside a function so we can call it whenever we want to function startCounter(imageLoader){ $('#counter_2').countdown({ image: 'img/digits.png', startTime: '00:03', timerEnd: function(){ callback(imageLoader) }, format: 'mm:ss' }) } // Takes care of whatever need to be done every time function callback(imageLoader){ // Replace image $('#image').attr('src', imageLoader.nextImage()); // Clear the finished counter, so a new can be constructed in its place $('#counter_2').empty(); // Construct a new counter and starts it startCounter(imageLoader); } function ImageLoader(images){ this.images = images; this.current = 0; this.nextImage = function(){ this.current = (this.current+1) % this.images.length; return this.images[this.current];; } } // Fill in images in this array imageLoader = new ImageLoader(['img/turd.png', 'img/guitar.gif', 'img/carrot.jpg', 'img/puppy.jpg']); // Set everything off! (Construct a new counter and starts it) startCounter(imageLoader); }); </script> <style type="text/css"> div.counter{ font-size: 36px; font-weight: bold; line-height: 77px; } </style> </head> <body> <div id="counter_2" class="counter"></div> <img id="image" src="img/turd.png" alt="Hot steaming turd"> </body> </html> Thanks everyone, I'm really stuck and really appreciate your help.
Canvas images do not load until click event... I want to load when page loads, how?
I am creating Battleships, the board game on an HTML5 canvas. I have a problem loading my ship images when the page is loaded. For some reason, the ship images only show when I click somewhere on the screen. background info: 1.I have 2 canvas elements, each with 2 contexts 2.If I put the PlayerGrid.js before the OpponentGrid.js I have to click on the screen to get my ships to show up. 3.The Draw() is what draws the grid, and the images once they are created from the createShips(). createships() simply creates different ship objects and assigns images to each object. 4.I DO TRY CALLING DRAW() in many places, the onload, and the createShips(), but they still do not show. Does anybody know what it could be? Is it a conflict in the context or canvases? The ship images DO show when I put the OpponentGrid.js BEFORE my PlayerGrid.js, but then there is a huge problem with my XMLHttpRequest that isn't worth solving. How else should I call my Draw method after everything is loaded? Should I call my Draw() in my Battleship.html at the end somewhere?
Here's how to be sure all your images are loaded before you use them Code and a Fiddle: http://jsfiddle.net/m1erickson/nD5jr/ <!doctype html> <html> <head> <link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css --> <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> <style> body{ background-color: ivory; } canvas{border:1px solid red;} </style> <script> $(function(){ var canvas1=document.getElementById("canvas1"); var ctx1=canvas1.getContext("2d"); var canvas2=document.getElementById("canvas2"); var ctx2=canvas2.getContext("2d"); var imageURLs=[]; var imagesOK=0; var imagesFailed=0; var imgs=[]; imageURLs.push("http://upload.wikimedia.org/wikipedia/commons/d/d4/New_York_City_at_night_HDR_edit1.jpg"); imageURLs.push("http://www.freebestwallpapers.info/bulkupload//20082010//Places/future-city.jpg"); loadAllImages(); function loadAllImages(){ for (var i = 0; i < imageURLs.length; i++) { var img = new Image(); imgs.push(img); img.onload = onLoad; img.onerror = onFail; img.src = imageURLs[i]; } } var imagesAllLoaded = function() { if (imagesOK+imagesFailed==imageURLs.length ) { // ALL IMAGES ARE NOW PROCESSED // ready to use loaded images // ready to handle failed image loads ctx1.drawImage(imgs[0],0,0,canvas1.width,canvas1.height); ctx2.drawImage(imgs[1],0,0,canvas2.width,canvas2.height); } }; function onLoad() { imagesOK++; imagesAllLoaded(); } function onFail() { // possibly log which images failed to load imagesFailed++; imagesAllLoaded(); }; }); // end $(function(){}); </script> </head> <body> <canvas id="canvas1" width=300 height=300></canvas><br/> <canvas id="canvas2" width=300 height=300></canvas> </body> </html>
FabricJS - add line to canvas and control only it's length
I am using FabricJS to develop a simple floor plan editor. When adding a Line (that should be a wall) to the canvas, I want the ability to control only the length of the line, not it's width-height. I have tried setting lockScalingY: true but the problem is that when adding a line the control handles are so close to each other that I can't interact only with the horizontal control handles... the corner handles actually block the horizontal handles... How can this be done?
Fine control of adjoining FabricJS lines The way graphics programs like photoshop deal with this common problem is to let the user position lines near the desired intersection and then use the arrowkeys to "nudge" the line into place pixel one at a time. The code below illustrates a rough solution that does the same thing for FabricJS lines: User selects a line. Turn off the control handles and borders. Let the user "nudge" the line into perfect alignment (here the line length is increased). Turn the the control handles and borders back On. This is just "proof of concept" code. In your production app: You'll probably want to use arrowkeys instead of buttons to "nudge". I made nudging go 10px at a time--you might do this 1px at a time. And when the user starts nudging, you'll automatically turn off the handles and borders for them. Here is code and a Fiddle: http://jsfiddle.net/m1erickson/dd742/ <!doctype html> <html> <head> <link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css --> <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> <script type="text/javascript" src="fabric.min.js"></script> <style> body{ background-color: ivory; padding:30px; } canvas{border: 1px solid red; } </style> <script> $(function(){ var canvas = new fabric.Canvas('canvas'); var selectedLine; var line1=newLine(50,100,150,100,"red"); var line2=newLine(160,50,160,150,"green"); canvas.add(line1,line2); function newLine(x1,y1,x2,y2,color){ var line=new fabric.Line( [x1,y1,x2,y2], {fill:color,strokeWidth:15,selectable:true} ); return(line); }; $("#hOff").click(function(){ selectedLine.hasBorders=false; selectedLine.hasControls=false; canvas.renderAll(); }); $("#hOn").click(function(){ selectedLine.hasBorders=false; selectedLine.hasControls=true; canvas.renderAll(); }); $("#shorter").click(function(){ changeLineLength(selectedLine,-10); canvas.renderAll(); }); $("#longer").click(function(){ changeLineLength(selectedLine,10); canvas.renderAll(); }); function changeLineLength(line,adjustment){ if(!selectedLine){return;} if(line.get("y1")==line.get("y2")){ // line is horizontal line.set("x2",line.get("x2")+adjustment); }else if(line.get("x1")==line.get("x2")){ // line is vertical line.set("y2",line.get("y2")+adjustment); }else{ // line is diagonal line.set("x2",line.get("x2")+adjustment); line.set("y2",line.get("y2")+adjustment); } } canvas.observe('object:selected', function(eventTarget) { var event=eventTarget.e; var target=eventTarget.target; selectedLine=target; }); }); // end $(function(){}); </script> </head> <body> <p>Select a line,</p><br/> <p>Turn handles Off</p><br/> <p>Make lines intersect by pressing longer/shorter</p><br/> <canvas id="canvas" width="600" height="200"></canvas> <button id="hOff">Handles Off</button> <button id="shorter">Shorter</button> <button id="longer">Longer</button><br/> <button id="hOn">Handles On</button> </body> </html>
May be helps somebody. Add handler to event 'object:selected': _objSelected Then at handler set unneeded control to false. function _objSelected(e) { if(e.target.objectType == 'line') { var cv = e.target._controlsVisibility; // mt - middle top, tl - top left and etc. cv.mt = cv.mb = cv.tl = cv.bl = cv.tr = cv.br = false; } } Also I added objectType (custom property) and padding (for beauty) to new object Line var obj = new fabric.Line([50, 50, 150, 50], { padding: 10, objectType: 'line' });