只是想知道是否有人已經在Javascript中完成了這項工作,或者如果我必須自己做 - 如果後者:我該怎麼做? (不要求一段代碼,只是好奇哪一種方法,你會使用)JavaScript中是否存在getColorBoundsRect()等價物?
2
A
回答
2
我有更好的解。沒有必要遍歷整個像素,只能通過邊界框外的遍歷。想想這樣,如果你想在1D中做同樣的事情:在數組中找到一個值的第一個和最後一個位置,你是否會遍歷整個數組?最好從頭開始,直到找到第一個值,然後從結束開始,直到找到最後一個值。以下代碼對2D也是如此。我沒有徹底地測試它(無論是正確還是速度),但它似乎有效,常識上說速度更快。
BitmapData.prototype.getColorBoundsRect = function(mask, color, findColor, rect){
findColor = typeof findColor !== 'undefined' ? findColor : true;
rect = typeof rect !== 'undefined' ? rect : new module.Rect(0, 0, this.width, this.height);
var l = rect.w - 1;
var r = 0;
var t = rect.h - 1;
var b = 0;
var data = this.context.getImageData(rect.x, rect.y, rect.w, rect.h).data;
// Scan from top to first pixel.
for (var i = 0; i < data.length; i += 4){
var val = module.RGBToHex({r:data[i], g:data[i+1], b:data[i+2], a:data[i+3]});
// console.log(val, mask, color, (val & mask) >>> 0)
if ((findColor && ((val & mask) >>> 0 == color)) || (!findColor && ((val & mask) >>> 0 != color))){
l = r = ((i/4) % rect.w);
t = b = Math.floor(i/4/rect.w);
break;
}
}
// We found nothing.
if (i >= data.length) {
return null;
}
// Scan from bottom to first pixel
for (var j = data.length - 4; j > i; j -= 4){
var val = module.RGBToHex({r:data[j], g:data[j+1], b:data[j+2], a:data[j+3]});
if ((findColor && ((val & mask) >>> 0 == color)) || (!findColor && ((val & mask) >>> 0 != color))){
l = Math.min(l, ((j/4) % rect.w))
r = Math.max(r, ((j/4) % rect.w))
b = Math.floor(j/4/rect.w);
break;
}
}
console.log(l, r, t, b);
// Scan from left
for (var x = 0; x < l; x ++){
for (var y = t + 1; y <= b; y ++){
i = (y * rect.w + x) * 4
var val = module.RGBToHex({r:data[i], g:data[i+1], b:data[i+2], a:data[i+3]});
if ((findColor && ((val & mask) >>> 0 == color)) || (!findColor && ((val & mask) >>> 0 != color))){
l = Math.min(l, x);
break;
}
}
}
console.log(l, r, t, b);
// Scan from right
for (var x = rect.w - 1; x > r; x --){
for (var y = t; y < b; y ++){
i = (y * rect.w + x) * 4
var val = module.RGBToHex({r:data[i], g:data[i+1], b:data[i+2], a:data[i+3]});
if ((findColor && ((val & mask) >>> 0 == color)) || (!findColor && ((val & mask) >>> 0 != color))){
r = Math.max(r, x);
break;
}
}
}
console.log(l, r, t, b)
return new module.Rect(l + rect.x, t + rect.y, (r - l), (b - t));
}
在此代碼BitmapData
只是包裝畫布對象及其context2d,和Rect
是{x: , y: , w: , h: }
對象。我不得不做一些鬼混RGBToHex,以確保我得到正數(UINT的)太:
module.RGBToHex = function(rgb) {
return (rgb.a << 24 | rgb.r<<16 | rgb.g<<8 | rgb.b) >>> 0;
};
+0
顯然是一個更美麗的版本 - 非常感謝;) – Peter
1
這裏是我的quick'n'dirty解決方案,也許somebody'll覺得有用;)
/**
* get a rectangle around color
* @param {...} ctx 2dCanvasObject to be scanned
* @return {Object} object storing the rectangle's data (x, y, w(idth), h(eight))
*/
function getColorBoundsRect(ctx) {
/**
* the canvas' context's data property (shorthand)
* @type {...}
*/
var data = ctx.data,
/**
* counter variable
* @type {Number}
*/
i = 0,
/**
* the "leftest" pixel that is not black (starts right, as we check if currently looped pixel (that is not black) is "lefter" than the current outerLeftPixel)
* @type {Number}
*/
outerLeftPixel = w-1,
/**
* the "rightest" pixel that is not black (starts left, as we check if currently looped pixel (that is not black) is "righter" than the current outerRightPixel)
* @type {Number}
*/
outerRightPixel = 0,
/**
* the "toppest" pixel that is not black (starts at bottom, as we check if currently looped pixel (that is not black) is "topper" than the current outerTopPixel)
* @type {Number}
*/
outerTopPixel = h-1,
/**
* the "bottomest" pixel that is not black (starts at top, as we check if currently looped pixel (that is not black) is "bottomer" than the current outerBottomPixel)
* @type {Number}
*/
outerBottomPixel = 0,
/**
* x coordinate of currently looped pixel
* @type {Number}
*/
x,
/**
* y coordinate of currently looped pixel
* @type {Number}
*/
y;
// loop through all pixels
// i equals the i'th pixel (0 is the upper left pixel, w*h is the bottom right pixel)
while (i < (data.length/4)) {
// check if currently looped pixel is anything else than black --> color
if ((data[i*4] + data[i*4+1] + data[i*4+2]) > 0) {
// set coordinates for the currently looped pixel
x = i % w; // if one row has 10px and i = 35, the x coordinate of the current pixel is 35 % 10 = 5
y = Math.floor(i/w); // if one row has 10px and i=35, the y coordinate of the current pixel is 35/10 = 3.5 (--> rounded off = 3)
// if the x coordinate of the current (colored) pixel is smaller than the current "leftest" pixel, set the x coordinate as new "leftest pixel"
// same procedure for the other values
if (x < outerLeftPixel) {
outerLeftPixel = x;
}
if (x > outerRightPixel) {
outerRightPixel = x;
}
if (y < outerTopPixel) {
outerTopPixel = y;
}
if (y > outerBottomPixel) {
outerBottomPixel = y;
}
}
++i;
}
// if there is color on the canvas, the outer[Right|Left|Bottom|Top]Pixel properties should have been updated accordingly and the following condition should be true
if (outerRightPixel > outerLeftPixel && outerBottomPixel > outerTopPixel) {
return {
x: outerLeftPixel,
y: outerTopPixel,
w: outerRightPixel - outerLeftPixel,
h: outerBottomPixel - outerTopPixel
};
}
// if there is no color on the canvas, return false, as there is no rectangle
else {
return false;
}
}
相關問題
- 1. WeakHashMap是否存在java.util.concurrent等價物?
- 2. Axiis是否存在非Adobe等價物?
- 3. 是否存在0x80的ascii等價物?
- 4. IBM Worklight - 是否存在Window.open()等價物?
- 5. ASP.NET MVC中是否存在JavaScript生成器的等價物?
- 6. 是否存在與SELECT ... COUNT(*)... GROUP BY ...等價的等價物?
- 7. JavaScript的Function.prototype.bind是否有Ruby等價物?
- 8. Java中是否存在std :: bitset等價物(或類似物)?
- 9. 是否存在。=用於自連接的JavaScript等價物?
- 10. 是否存在JavaScript方法encode()的Objective C等價物?
- 11. 在Python中是否有sessionInfo()等價物?
- 12. 在Java中是否有TweenMax等價物
- 13. 在java中是否有array_intersect()等價物?
- 14. 在Doxygen中是否有@inheritDoc等價物?
- 15. 在Python中是否有Rake等價物?
- 16. 在Ramda中是否有R.notEquals等價物?
- 17. 在Windows中是否有XEmbed等價物?
- 18. 在Ruby的發送中,Javascript/Coffeescript/jQuery中是否存在等價物?
- 19. C++中是否存在Python中的「in」函數的等價物?
- 20. 在PowerShell中是否存在「... || die」等價物?
- 21. 在C#中是否存在boost :: shared_ptr <T>等價物?
- 22. 在Ruby中是否存在addslashes等價物?
- 23. 在Swift中是否存在decltype等價物?
- 24. 在C++中是否存在C#SecureString等價物?
- 25. 在C#Windows窗體中是否存在QTimer :: singleShot等價物?
- 26. 在jquery中是否存在一個Angular Multiple選擇等價物?
- 27. 在C++/CLI中是否存在C#的不安全等價物?
- 28. 在Python 3中是否存在與tokenize import pseudoprog.match的等價物?
- 29. 在SQL Server Management Studio中是否存在SELECT ... INTO OUTFILE等價物?
- 30. 在Ruby 1.8.5中是否存在Array#each_slice()的等價物?
你或許應該說明你想在這裏,而不是做的只是鏈接到一些外部網站的內容。如果該網站更改其網址或脫機,您的問題將無法理解。 – Pointy
一個人不需要這個鏈接 - 我認爲這將是很好的指出我需要它,但我可以刪除它;) – Peter