[英]How can I crop an image beyond image boundary like I want to make a 1:1 image from a 4:3 image by adding transparent/white margins to it?
[英]Algorithm to make image white and transparent
這種影響(如下圖所示)是通過幾個簡單的Photoshop步驟完成的,顏色部分變為白色,背景(各種陰影為白色,灰色)變透明了。 用畫布可以實現嗎?
以下圓圈內的圖像是最終結果。
圖像最初是彩色的,就像頂部圖像中的第二個是這樣的:
看到中間的那個圓圈,基本上所有白色都以鋸齒的方式被切掉了。
與此zoho徽標相同:
倒數第二個最初是這樣的:
除了紅色R在中間只是Y,而不是在圖像中看到的所有文本和綠色條帶之外,它周圍只有灰色陰影,帶有一些粒狀紋理。 然后通過photoshop將Y變成透明的,將紋理和印記制作成實心的,除去3d陰影等。
通過photoshop算法將其放置在yandex戳上方,即可達到此目的(我將白色替換為黑色,以進行演示/可見性的偽裝)
在Photoshop算法之后,這是鋸齒狀的,但是在最終應用中,圖像被縮小到80x80px左右,這使它看起來真正平滑且抗鋸齒。 因此,真正的最終結果是看起來非常不錯。
問題是多方面的,因為某些區域需要使用不同的方法,例如,最后一張圖像需要將主文本轉換為白色,但要保持透明,而同一圖像的底部欄是實心的,但需要將白色文本保留而要刪除的純色背景。
通過實施工具來選擇區域並手動應用各種運算符是可行的-自動處理將比看起來要面臨的挑戰大得多。
您可以要求用戶僅上傳帶有Alpha通道的圖像。 為此,您可以簡單地將每個非透明像素替換為白色。 在我看來,它不僅僅是技術問題,而是政策問題。
取徽標:
var img = new Image(); img.crossOrigin = ""; img.onload = process; img.src = "http://i.imgur.com/HIhnb4A.png"; // load the logo function process() { var canvas = document.querySelector("canvas"), // canvas ctx = canvas.getContext("2d"), // context w = this.width, // image width/height h = this.height, idata, data32, len, i, px; // iterator, pixel etc. canvas.width = w; // set canvas size canvas.height = h; ctx.drawImage(this, 0, 0); // draw in image idata = ctx.getImageData(0, 0, w, h); // get imagedata data32 = new Uint32Array(idata.data.buffer); // use uint32 view for speed len = data32.length; for(i = 0; i < len; i++) { // extract alpha channel from a pixel px = data32[i] & 0xff000000; // little-endian: ABGR // any non-transparency? ie. alpha > 0 if (px) { data32[i] = px | 0xffffff; // set this pixel to white, keep alpha level } } // done ctx.putImageData(idata, 0, 0); }
body {background:gold}
<canvas></canvas>
現在問題很容易發現:“ @”字符很穩定,因為它后面沒有透明性。 要使其自動化,首先需要剔除所有白色,然后應用上面演示的過程。 但是,這可能在這種情況下可行,但對大多數人來說可能不是一件好事。
還存在抗鋸齒問題,因為我們不分析白色像素周圍的邊緣,因此無法知道要剔除多少白色。 另一個可能的挑戰是經過ICC校正的圖像,根據所使用的ICC配置文件,瀏覽器支持等,白色可能不是白色。
但是,從某種程度上講,它是可行的-采取上述代碼,並以預先步驟剔除此徽標的全白像素:
var img = new Image(); img.crossOrigin = ""; img.onload = process; img.src = "http://i.imgur.com/HIhnb4A.png"; // load the logo function process() { var canvas = document.querySelector("canvas"), // canvas ctx = canvas.getContext("2d"), // context w = this.width, h = this.height, idata, data32, len, i, px; // iterator, pixel etc. canvas.width = w; // set canvas size canvas.height = h; ctx.drawImage(this, 0, 0); // draw in image idata = ctx.getImageData(0, 0, w, h); // get imagedata data32 = new Uint32Array(idata.data.buffer); // use uint32 view for speed len = data32.length; for(i = 0; i < len; i++) { px = data32[i]; // pixel // is white? then knock it out if (px === 0xffffffff) data32[i] = px = 0; // extract alpha channel from a pixel px = px & 0xff000000; // little-endian: ABGR // any non-transparency? ie. alpha > 0 if (px) { data32[i] = px | 0xffffff; // set this pixel to white, keep alpha level } } ctx.putImageData(idata, 0, 0); }
body {background:gold}
<canvas></canvas>
用這個
private draw(base64: string) {
// example size
const width = 200;
const height = 70;
const image = new Image();
image.onload = () => {
const canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0);
const imageData = ctx.getImageData(0, 0, width, height);
for (let x = 0; x < imageData.width; x++) {
for (let y = 0; y < imageData.height; y++) {
const offset = (y * imageData.width + x) * 4;
const r = imageData.data[offset];
const g = imageData.data[offset + 1];
const b = imageData.data[offset + 2];
// if it is pure white, change its alpha to 0
if (r == 255 && g == 255 && b == 255) {
imageData.data[offset + 3] = 0;
}
}
}
ctx.putImageData(imageData, 0, 0);
// output base64
const result = canvas.toDataURL();
};
image.src = base64;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.