cocos获取图片像素

 
//一下是获取某个像素的透明值,以此类推可以回去r,g,b的值
Image *myImage = new Image();
myImage->initWithImageFile("test.png");
unsigned char *data = myImage->getData();  //这里就是图片数据了
//根据刚刚计算的相对坐标值,计算出触摸点代表了哪一个像素点      然后再提取出该像素点的alpha值
//注意:因为图片坐标(0,0)是在左上角,所以要和触摸点的Y转换一下,也就是“(myImage->getHeight() - (int)(ps.y) - 1)”
//该data值是把二维数组展开成一个一维数组,因为每个像素值由RGBA组成,所以每隔4个char为一个RGBA,并且像素以横向排列
int pa = 4 * ((myImage->getHeight() - (int)(ps.y) - 1) * myImage->getWidth() + (int)(ps.x)) + 3;
unsigned int ap = data[pa];

转:https://blog.zengrong.net/post/2104.html

 

我采用的是这种办法。流程如下:

  1. 在需要图片像素值的时候,将这张图片使用 FrameBuffer 重新绘制成像素;
  2. 获得相关像素的颜色值;
  3. 删除已经获得的像素。

这种方法的弊端如下:

  1. 如果要取得的像素图片巨大,可能对性能有影响;
  2. 每次的数据没有缓存,频繁执行的话性能消耗巨大。

当然,如果确实需要在同一张图片上多次操作,缓存可以程序员自己来做。

为了实现这个流程,我修改了 CCImage.h,增加了两个方法 getColor4B 和 getColor4F :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ccColor4B getColor4B(float x, float y)
{
	ccColor4B color = { 0, 0, 0, 0 };
	int ix = (int)x - 1;
	int iy = (int)y - 1;
	m_pData += (iy*getWidth() + ix) * 4;
	color.r = *(m_pData++);
	color.g = *(m_pData++);
	color.b = *(m_pData++);
	color.a = *(m_pData++);
	return color;
};

ccColor4F getColor4F(float x, float y)
{
	return ccc4FFromccc4B(getColor4B(x, y));
};

2014-10-24更新:上面的代码没有考虑越界问题,在传递的坐标不在图像中时,程序会崩溃。

最新的代码改正了问题,请参考 github 。

由于 CCImage 是跨平台实现的,所以放在头文件中比放在实现文件中要方便许多。否则,就需要在 CCImage 的若干个平台相关实现中分别执行实现了。

下面是 quick-cocos2d-x 中的实现代码,我将其放在了 CCSpriteExtned.lua 框架中,这样能让所有的 CCSprite 实例都支持这个方法。

具体的实现请看代码,不解释了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
-- NOTE!!! The method is very slowly! Please use it in carefully.
-- @param __point A coordinate for color.
-- @param __convertToNodeSpace Optional, default is true, convert a coordinate to node space from world space.
-- @param __isFloat Optional, default is false, convert a coordinate to node space from world space.
function CCSpriteExtend:getColor(__point, __convertToNodeSpace, __isFloat)
	if __convertToNodeSpace == nil then
		__convertToNodeSpace = true
	end
	if __convertToNodeSpace then
		__point = self:convertToNodeSpace(__point)
	end
	-- Create a new Texture to get the pixel datas.
	local __size = self:getContentSize()
	local __rt = CCRenderTexture:create(__size.width, __size.height)
	-- Hold the old anchor and position to restore it late on.
	local __oldAnchor = self:getAnchorPoint()
	local __oldPos = self:getPositionInCCPoint()
	-- Move the sprite to left bottom.
	self:align(display.LEFT_BOTTOM, 0,0)
	--print("getColor:", __point.x, __point.y, __size.width, __size.height)
	-- Render the sprite to get a new texture.
	__rt:begin();
	self:visit()
	__rt:endToLua();
	-- Restore the original anchor and position.
	self:setAnchorPoint(__oldAnchor)
	self:setPosition(__oldPos)
	local __img = __rt:newCCImage(false)
	local __color = nil
	if __isFloat then
		__color = __img:getColor4F(__point.x, __point.y)
	else
		__color = __img:getColor4B(__point.x, __point.y)
	end
	return __color, __rt
end

-- Only get a alpha value.
function CCSpriteExtend:getColorAlpha(__point, __convertToNodeSpace, __isFloat)
	local color = self:getColor(__point, __convertToNodeSpace, __isFloat)
	return color.a
en

这个方法已经合并进入 quick-cocos2d-x 的 develop 分支

2014-10-24更新:由于 newCCImage 方法在 C++ 中是请求堆内存并返回一个指针。因此必须手动释放。上面的代码没有考虑释放问题,将会导致内存泄露。

最新的代码改正了问题,请参考 github 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值