只是想知道是否有人已经在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