2015-08-27 5 views
3

Можно ли сохранить или экспортировать только определенную часть холста, а не весь холст?Сохранить только определенную часть HTML-холста

http://i.stack.imgur.com/hmvYh.jpg

В тот момент, когда я сохранить файл я получаю состав плюс прозрачный фон (светло-синий, в приведенном выше примере), всего холста элемента у меня есть на сайте. То, что я хотел бы получить, - это только серый регион (который может состоять из нескольких изображений и текстовых элементов).

+0

Возможный дубликат [Как извлечь часть изображения в холсте и использовать его в качестве фонового изображения для div?] (Http://stackoverflow.com/questions/35033357/how-do-i-extract- a-part-of-an-image-in-canvas-and-use-it-as-background-image) – Kaiido

ответ

1

Да, можно, но в то время как я делал the JSFiddle, Майкл Ласло бил меня к удару. В любом случае, я поместил некоторое время в это, поэтому я все еще отправляю свой ответ.

Во-первых, вам нужно взять clipping изображения в вашем полотне. Это довольно просто. Я сделал еще один холст (скрытый один) и использовал context.drawImage

var hidden_ctx = hidden_canvas.getContext('2d'); 

hidden_ctx.drawImage(
    MainCanvas, 
    startClippingX, 
    startClippingY, 
    clippingWidth, 
    clippingHeight, 
    pasteX, 
    pasteY, 
    pasteWidth, 
    pasteHeight 
); 

Теперь нам нужно URL данных из этого холста, чтобы мы могли загрузить содержимое. Для этого мы будем использовать метод canvas.toDataURL.

var data_url = hidden_canv.toDataURL("image/png").replace("image/png", "image/octet-stream"); 

Теперь все, что нам нужно сделать, это сделать ссылку для скачивания (a элемент с href атрибутом нашего data_url) и мы сделали!

Спасибо, ребята, и мне жаль, что я не был достаточно быстрым, чтобы получить червя на этом, что делает меня очень грустным. Не менее my JSFiddle должно быть полезно.

+0

Хорошо, получил концепцию создания невидимого холста, и это должно работать очень хорошо. Теперь, поскольку это было очень упрощенное дело, мне интересно, можно ли получить координаты всех объектов в холсте (прямо из холста, а не зацикливания переменных), чтобы я мог находить верхние левые + нижние правые позиции (чтобы получить высоту и ширину) http://oi62.tinypic.com/33bintd.jpg? – mindo

+0

Я не совсем уверен, что вы спрашиваете здесь, не могли бы вы быть более конкретными? Кроме того, 'canvas' не содержит« объектов ». Как только что-либо нарисовано на холсте, это не что иное, как массив пикселей. Нет ни одной коллекции истории ничьей нигде в контексте. Если вы хотите сохранить ссылку на пути, которые вы нарисовали на холсте, или ваши «объекты», вам нужно будет сделать это самостоятельно, сохраните свою информацию в массиве, и вам нужно будет пройти через этот массив. – WebWanderer

+0

У вас все правильно (вопрос). Благодарю. – mindo

2

Предположит, у вас есть холст под названием oldCanvas, и вы хотите, чтобы сохранить прямоугольную область ширины w и высоту h с левым верхним углом в x, y.

Начните с создания нового canvas элемента шириной w и высота h:

var newCanvas = document.createElement('canvas'); 
newCanvas.width = w; 
newCanvas.height = h; 

Теперь скопировать прямоугольную область на новый холст:

var newContext = newCanvas.getContext('2d'); 
newContext.drawImage(oldCanvas, x, y, w, h, 0, 0, w, h); 

Наконец, сохранить новый холст, используя toDataUrl() или какой бы метод вы ранее не использовали для сохранения всего холста.

Например, вы можете сделать изображение из нового холста:

var newImage = document.createElement('img'); 
newImage.src = newCanvas.toDataURL(); 

Затем добавить новое изображение на веб-странице:

document.body.appendChild(newImage); 

Или, может быть, у вас есть контейнер div что вы хотите добавить его.

В любом случае, как только изображение находится в документе, вы можете щелкнуть его правой кнопкой мыши и сохранить его, как обычно.

Я реализовал этот подход в следующем фрагменте. Когда вы запустите его, холст будет беспорядочно окрашен. Нажмите и перетащите на холст, чтобы выбрать регион, который вы хотите загрузить. Справа появляется новое загружаемое изображение.

// Returns a random RGB string (RGBA if alpha is true). 
 
function randomColor(alpha) { 
 
    var rgb = [ 
 
    Math.floor(Math.random() * 255), 
 
    Math.floor(Math.random() * 255), 
 
    Math.floor(Math.random() * 255) 
 
    ]; 
 
    if (alpha) { 
 
    rgb.push(Math.random()); 
 
    } 
 
    return 'rgb' + (alpha ? 'a' : '') + '(' + rgb.join(', ') + ')'; 
 
} 
 

 
// Makes a random picture for use in the demonstration. 
 
function makeCanvas() { 
 
    var canvas = document.getElementById('oldCanvas'), 
 
     context = canvas.getContext('2d'), 
 
     width = canvas.width = 400, 
 
     height = canvas.height = 500; 
 
    context.fillStyle = randomColor(); 
 
    context.fillRect(0, 0, width, height); 
 
    for (var i = 0; i < 200; ++i) { 
 
    var x = Math.floor(Math.random() * width), 
 
     y = Math.floor(Math.random() * height), 
 
     w = Math.floor(Math.random() * width/5), 
 
     h = Math.floor(Math.random() * height/5); 
 
    context.fillStyle = randomColor(true); 
 
    if (Math.floor(Math.random() * 2) === 0) { 
 
     context.fillRect(x - w/2, y - h/2, w, h); 
 
    } else { 
 
     context.beginPath(); 
 
     context.arc(x, y, w, 0, 2 * Math.PI); 
 
     context.closePath(); 
 
     context.fill(); 
 
    } 
 
    } 
 
    return canvas; 
 
}; 
 

 
window.onload = function() { 
 
    var oldCanvas = makeCanvas(), 
 
     oldContext = oldCanvas.getContext('2d'), 
 
     targetImage = document.getElementById('targetImage'), 
 
     downloadContainer = document.getElementById('downloadContainer'), 
 
     selectCanvas = document.getElementById('selectCanvas'), 
 
     selectContext = selectCanvas.getContext('2d'), 
 
     width = selectCanvas.width = oldCanvas.width, 
 
     height = selectCanvas.height = oldCanvas.height; 
 
    selectContext.fillStyle = '#000'; 
 
    downloadContainer.style.left = width + 25 + 'px'; 
 
    var clipCanvas = document.createElement('canvas'), 
 
     clipContext = clipCanvas.getContext('2d'); 
 
    downloadContainer.appendChild(clipCanvas); 
 
    selectCanvas.onmousedown = function (event) { 
 
    var x0 = Math.max(0, Math.min(event.clientX, width)), 
 
     y0 = Math.max(0, Math.min(event.clientY, height)); 
 
    targetImage.style.display = 'none'; 
 
    function update(event) { 
 
     var x = Math.max(0, Math.min(event.clientX, width)), 
 
      y = Math.max(0, Math.min(event.clientY, height)), 
 
      dx = x - x0, w = Math.abs(dx), 
 
      dy = y - y0, h = Math.abs(dy); 
 
     selectContext.clearRect(0, 0, width, height); 
 
     selectContext.fillRect(x0, y0, dx, dy); 
 
     clipCanvas.width = w; 
 
     clipCanvas.height = h; 
 
     if (w*h == 0) { 
 
     downloadContainer.style.visibility = 'hidden'; 
 
     } else { 
 
     downloadContainer.style.visibility = 'visible'; 
 
     clipContext.drawImage(oldCanvas, 
 
      x0 + Math.min(0, dx), y0 + Math.min(0, dy), w, h, 
 
      0, 0, w, h); 
 
     downloadContainer.style.visibility = (w*h == 0 ? 'hidden' : 'visible'); 
 
     downloadContainer.style.top = Math.min(y0, y) + 'px'; 
 
     } 
 
    }; 
 
    update(event); 
 
    selectCanvas.onmousemove = update; 
 
    document.onmouseup = function (event) { 
 
     selectCanvas.onmousemove = undefined; 
 
     document.onmouseup = undefined; 
 
     targetImage.src = clipCanvas.toDataURL(); 
 
     targetImage.style.display = 'block'; 
 
    }; 
 
    }; 
 
};
body, div, canvas, img { 
 
    margin: 0; 
 
    padding: 0; 
 
} 
 
#targetImage { 
 
    display: none; 
 
    position: absolute; 
 
    left: 0; 
 
    top: 0; 
 
} 
 
canvas { 
 
    display: block; 
 
} 
 
#oldCanvas, #selectCanvas, #downloadContainer { 
 
    position: fixed; 
 
} 
 
#downloadContainer { 
 
    visibility: hidden; 
 
} 
 
#downloadContainer .label { 
 
    position: absolute; 
 
    width: 500px; 
 
    bottom: -20px; 
 
    font-family: sans-serif; 
 
    font-size: 17px; 
 
    color: #444; 
 
} 
 
#selectCanvas { 
 
    opacity: 0.5; 
 
    cursor: default; 
 
}
<canvas id="oldCanvas"></canvas> 
 

 
<canvas id="selectCanvas"></canvas> 
 

 
<div id="downloadContainer"> 
 
    <div class="label"> right-click above to download this image </div> 
 
    <img id="targetImage"> 
 
</div>

+0

Это очень сложный пример, но мне нужно сделать это программно, хотя этот снайпер будет определенно полезен для других ! Спасибо за вашу помощь! – mindo

+0

Что именно вы хотите делать программно? –

Смежные вопросы