Ejemplo n.º 1
0
/*!
	マスクの可視部分の範囲を返す
	@param[in] mask マスク
	@param[out] lprc 範囲
*/
_EXPORT void ucvGetMaskRect(const IplImage *mask, LPRECT lprc)
{
	if(!mask) return;

	//判定のための初期値
	lprc->left = 0;
	lprc->top = 0;
	lprc->bottom = mask->height;
	lprc->right = mask->width;
	
	uint8_t* pmask;

	//上から下へ走査
	for(int y=0; y<mask->height; y++){
		pmask = GetPixelAddress(mask, 0, y);
		for(int x=0; x<mask->width; x++){
			if((*pmask) != 0){
				lprc->top = y;
				goto uptodown;
			}
			pmask++;
		}
	}
uptodown:
	//下から上へ走査
	for(int y=mask->height-1; y>=0; y--){
		pmask = GetPixelAddress(mask, 0, y);
		for(int x=0; x<mask->width; x++){
			if((*pmask) != 0){
				lprc->bottom = y+1;
				goto lefttoright;
			}
			pmask++;
		}
	}
	lprc->bottom = 0;
lefttoright:
	//左から右へ走査
	for(int x=0; x<mask->width; x++){
		for(int y=0; y<mask->height; y++){
			int data = GetMaskDataPos(mask, x, y);
			if(data != 0){
				lprc->left = x;
				goto righttoleft;
			}
		}
	}
righttoleft:
	//右から左へ走査
	for(int x=mask->width-1; x>=0; x--){
		for(int y=0; y<mask->height; y++){
			int data = GetMaskDataPos(mask, x, y);
			if(data != 0){
				lprc->right = x+1;
				return;
			}
		}
	}
	lprc->right = 0;
}
Ejemplo n.º 2
0
static void FillMask(IplImage *image, uint8_t setnum, int x, int y)
{
	if(( 0 <= x && x <= image->width -1 )&&
		(0 <= y && y <= image->height -1 ) )
	{

		uint8_t cl = GetMaskDataPos(image, x, y);
		if(cl == 255){
			::MessageBox(NULL, "", "", MB_OK);
		}
		SetMaskDataPos(image, setnum, x, y);

		//上
		if(GetMaskDataPos(image, x, y-1) == cl){
			FillMask(image, setnum, x, y-1);
		}

		//右
		else if(GetMaskDataPos(image, x+1, y) == cl){
			FillMask(image, setnum, x + 1, y);
		}

		//下
		else if(GetMaskDataPos(image, x, y-1) == cl){
			FillMask(image, setnum, x, y-1);
		}

		//左
		else if(GetMaskDataPos(image, x-1, y) == cl){
			FillMask(image, setnum,  x-1, y);
		}
	}
}
Ejemplo n.º 3
0
/*!
	maskの範囲lprcをdst_maskにコピーする
	@param[in] mask マスク
	@param[in] lprc 範囲
	@param[out] dst_mask 出力結果
*/
_EXPORT void CutMask(const IplImage *mask, const LPRECT lprc, IplImage *dst_mask)
{
	int x,y;
	for(y=lprc->top; y<= lprc->bottom; y++){
		for(x=lprc->left; x<= lprc->right; x++){
			int data = GetMaskDataPos(mask, x, y);
			SetMaskDataPos(dst_mask, x - lprc->left, y - lprc->top, data);
		}
	}
}
Ejemplo n.º 4
0
/*!
	srcをdstに転送
	@param[out] dst 出力先
	@param[in] posX dst転送開始位置
	@param[in] posY dst転送開始位置
	@param[in] width 転送する画像幅
	@param[in] height 転送画像高さ
	@param[in] src 転送元画像
	@param[in] startX 転送元画像開始位置
	@param[in] startY 転送元画像開始位置
*/
_EXPORT void BltMaskToMask(IplImage* dst, int posX, int posY, int width, int height, 
				   const IplImage* src, int startX, int startY)
{
	int x,y;
	for(y=0; y<height; y++){
		for(x=0; x<width; x++){
			uint8_t data = GetMaskDataPos(src, x + startX, y + startY);
			SetMaskDataPos(dst, posX + x, posY + y, data);
		}
	}
}
Ejemplo n.º 5
0
void MoveSelectImage::MoveImage(LPINPUT_DATA lpd, LPPOINT beforPt)
{
	ImgFile *f = m_pImgEdit->GetActiveFile();
	if(f){
		int shiftX = lpd->x - beforPt->x;
		int shiftY = lpd->y - beforPt->y;
		ImgLayer *l = f->GetSelectLayer();		
		if(!l){
			IEMessageBox("レイヤーが選択されていません。");
		}
		const IplImageExt *ImgExt = l->GetDrawImage();
		IplImage* mask = f->GetSelectMask();


		move_X += shiftX;
		move_Y += shiftY;
		
		RECT newRc;
		newRc.top  = beforRc.top + shiftY;  newRc.bottom = beforRc.bottom + shiftY;
		newRc.left = beforRc.left + shiftX; newRc.right  = beforRc.right + shiftX;
		
		//
		RECT rc;
		OrRect(&beforRc, &newRc, &rc);

		//画像の移動
		m_editNode->to_rect = newRc;

		//mask zero clear
		cvSet(mask, cvScalar(0));

		//マスクの移動
		for(int y=0; y < move_mask->height; y++){
			for(int x=0; x < move_mask->width; x++){
				SetMaskDataPos(mask,
					x + move_X + maskRc.left,
					y + move_Y + maskRc.top,
					GetMaskDataPos(move_mask, x, y));
			}
		}


		//画像の更新
		UPDATE_DATA data;
		data.isAll = false;
		data.rect = rc;
		data.update_flag = UPDATE_FLAG::UPDATE_SELECT_LAYER_ALL_NODE;
		f->PushUpdateData(&data);

		beforRc = newRc;
	}
}
Ejemplo n.º 6
0
_EXPORT void FillCloseArea(IplImage *mask, uint8_t setnum)
{
	CvLine2D64f_Vec line_Vec;

	for (int y=0; y<mask->height; y++) {
		bool isWrite = false;
		bool isData = false;
		int count = 0;
		bool isBeforData = false;
		CvLine2D64f line;
		for (int x=0; x<mask->width; x++) {

			if (0 != GetMaskDataPos(mask, x, y)) {
				isData = true;
			}
			else {
				isData = false;
			}

			if (isData == true && isBeforData == false) {
				count++;
				if (count == 1) {
					line.start.x = x;
					line.start.y = y;
				}
				else if (count == 2) {
					line.end.x = x;
					line.end.y = y;
					line_Vec.push_back(line);
					count = 0;
				}
			}


			isBeforData = isData;
		}
	}

	CvLine2D64f_Vec::iterator itr = line_Vec.begin();
	for(; itr != line_Vec.end(); itr++){
		LineMask(mask, setnum, &((*itr).start), &((*itr).end));
	}
}
Ejemplo n.º 7
0
void AddFillCircleMaskAA3(
	IplImage* dst,
	double center_x,
	double center_y,
	double r,
	double aa_d,
	uint8_t setnum,
	uint8_t alpha)
{
	assert(dst);
	assert(r > 0);
	assert(0.0 < aa_d);

	double aa_min_d = r-aa_d;
	double aa_max_d = r+aa_d;

	double inv_alpha = alpha / 255.0;

	int start_x = (int)(center_x - aa_max_d);
	int start_y = (int)(center_y - aa_max_d);
	int end_x = (int)(center_x + aa_max_d);
	int end_y = (int)(center_y + aa_max_d);

	if(start_x < 0) start_x=0;
	if(start_y < 0) start_y=0;
	if(end_x >= dst->width) end_x = dst->width-1;
	if(end_y >= dst->height) end_y = dst->height-1;

	//浮動小数に定数を掛けて整数として計算する
	int FIXMUL = 32;
	int HF_FIXMUL = (int)FIXMUL/2.0;
	int ir = (int)(r * FIXMUL);
	int icenter_x = (int)(center_x * FIXMUL);
	int icenter_y = (int)(center_y * FIXMUL);

	
	int x,y;
	for(y=start_y; y<=end_y; y++){
		for(x=start_x; x<=end_x; x++){
			//int fx = x * FIXMUL - icenter_x;
			//int fy = y * FIXMUL - icenter_y;

			//bool inside0 = false; //左上
			//bool inside1 = false; //右上
			//bool inside2 = false; //左下
			//bool inside3 = false; //右下

			//if(!is_small){
			//	if((fx*fx + fy*fy) <= ir*ir) inside0 = true;
			//	if(((fx + FIXMUL)*(fx + FIXMUL) + fy*fy) <= ir*ir) inside1 = true;
			//	if((fx*fx + (fy + FIXMUL)*(fy + FIXMUL)) <= ir*ir) inside2 = true;
			//	if(((fx + FIXMUL)*(fx + FIXMUL) + (fy + FIXMUL)*(fy + FIXMUL)) <= ir*ir) inside3 = true;
			//}
			//else{
			//	is_small = true;
			//}

			//bool outside = !inside0 && !inside1 && !inside2 && !inside3;
			//if(outside){
			//	continue;
			//}

			//bool notaa = inside0 && inside1 && inside2 && inside3;
			//if(notaa){
			//	SetMaskDataPos(dst, x, y, setnum*inv_alpha);
			//}
			//else{
				uint8_t pix;
				double fr = sqrt((double)(x-center_x+0.5)*(x-center_x+0.5)+(y-center_y+0.5)*(y-center_y+0.5));
				if(fr < aa_min_d){
					pix = setnum*inv_alpha;
				}
				else if(fr >= aa_max_d){
					pix = 0;
				}
				else{
					double tmp = 1.0 - (fr - aa_min_d)/(aa_max_d - aa_min_d);
					pix = tmp * setnum*inv_alpha;
				}

				if(pix > GetMaskDataPos(dst, x, y)){
					SetMaskDataPos(dst, x, y, pix);
				}
			//}
		}
	}
}
Ejemplo n.º 8
0
void AddFillCircleMaskAA(
	IplImage* dst,
	double center_x,
	double center_y,
	double r,
	int div,
	uint8_t setnum,
	uint8_t alpha)
{
	assert(dst);
	assert(r > 0);

	bool is_small = false;
	if(r <= 3) is_small = true;

	int start_x = (int)(center_x - r);
	int start_y = (int)(center_y - r);
	int end_x = (int)(center_x + r);
	int end_y = (int)(center_y + r);

	if(start_x < 0) start_x=0;
	if(start_y < 0) start_y=0;
	if(end_x >= dst->width) end_x = dst->width-1;
	if(end_y >= dst->height) end_y = dst->height-1;

	//固定小数表現する
	int FIXMUL = 32;
	int ir = (int)(r * FIXMUL);
	int icenter_x = (int)(center_x * FIXMUL);
	int icenter_y = (int)(center_y * FIXMUL);

	int dr = (int)(r * div);
	int dcenter_x = (int)(center_x * div);
	int dcenter_y = (int)(center_y * div);

	double dalpha = alpha / 255.0;
	
	int x,y;
	for(y=start_y; y<=end_y; y++){
		for(x=start_x; x<=end_x; x++){
			int fx = (x << 5) - icenter_x; //x * FIXMUL - icenter_x;
			int fy = (y << 5) - icenter_y; //y * FIXMUL - icenter_y;

			bool inside0 = false; //左上
			bool inside1 = false; //右上
			bool inside2 = false; //左下
			bool inside3 = false; //右下

			if(!is_small){
				if((fx*fx + fy*fy) <= ir*ir) inside0 = true;
				if(((fx + FIXMUL)*(fx + FIXMUL) + fy*fy) <= ir*ir) inside1 = true;
				if((fx*fx + (fy + FIXMUL)*(fy + FIXMUL)) <= ir*ir) inside2 = true;
				if(((fx + FIXMUL)*(fx + FIXMUL) + (fy + FIXMUL)*(fy + FIXMUL)) <= ir*ir) inside3 = true;
			}
			else{
				inside0 = true;
			}

			bool outside = !inside0 && !inside1 && !inside2 && !inside3;
			if(outside){
				continue;
			}

			bool notaa = inside0 && inside1 && inside2 && inside3;
			if(notaa){
				SetMaskDataPos(dst, x, y, setnum*dalpha);
			}
			else{
				//
				int c = 0;
				int i,j;
				for(j=0; j<div; j++){
					for(i=0; i<div; i++){
						if((x*div+i - dcenter_x)*(x*div+i - dcenter_x) + (y*div+j - dcenter_y)*(y*div+j -  dcenter_y) < dr*dr)
							c++;
					}
				}

				int d = 255* c / (div*div);
				uint8_t val = setnum*(d/255.0)*dalpha;
				if(val > GetMaskDataPos(dst, x, y)){
					SetMaskDataPos(dst, x, y, val);
				}
			}
		}
	}
}
Ejemplo n.º 9
0
_EXPORT void RadiallyBlur(const IplImage* src, IplImage* dst, double ef)
{
	assert(src->nChannels == dst->nChannels);

	int center_x = src->width/2;
	int center_y = src->height/2;

	int i,x,y;
	int xx, yy;
	int dx, dy;
	int pat_sum, pat;
	double rate;
	double rad, dis, disI;
	double disMax = sqrt((double)src->height*src->height + src->width*src->width);

	int r, g, b, a=255;
	int sampling_r, sampling_g, sampling_b, sampling_a;
	for(y=0; y<src->height; y++){
		for(x=0; x<src->width; x++){
			dx = x - center_x;
			dy = y - center_y;

			if(dx != 0) rad = atan((double)dy/dx);
			else rad = _PI_/2.0;

			dis = sqrt((double)dx*dx + dy*dy); //distance of from center to (x, y)
			rate = ef * dis / disMax;
			rate /= (double)NN;
			pat_sum = 0;

			for(i=0; i<NN; i++){
				if(i == NF) pat = 3;
				else pat = 1;

				disI = (double)(i-NF)*rate;
				xx = (int)(disI*cos(rad)) + x;
				yy = (int)(disI*sin(rad)) + y;
			
				//read pixel
				switch(src->nChannels){
					case 1:
						a = GetMaskDataPos(src, x, y);
						sampling_a = a * pat;
						break;
					case 3:
						break;
					case 4:
						break;
				}
				pat_sum += pat;
			}

			//write pixel
			switch(dst->nChannels){
				case 1:
					SetMaskDataPos(dst, x, y, a/pat_sum);
					break;
				case 3:
					break;
				case 4:
					break;
			}
		}


	}
}
Ejemplo n.º 10
0
void MoveSelectImage::OnMouseLButtonDown(LPINPUT_DATA lpd)
{
	move_X = 0;
	move_Y = 0;

	startPt.x = beforPt.x = lpd->x;
	startPt.y = beforPt.y = lpd->y;

	ImgFile *f = m_pImgEdit->GetActiveFile();
	if(f){
		int g,b,r,a;
		ImgLayer* l = f->GetSelectLayer();
		if(!l){
			IEMessageBox("レイヤーが選択されていません。");
		}

		const IplImageExt *layer_img_ext =  l->GetDrawImage();
		
		IplImage *mask = f->GetSelectMask();
		
		//選択範囲が収まる矩形を求める
		GetMaskRect(mask, &maskRc);
		//レイヤーの有効範囲を求める
		layer_img_ext->GetMaxRangeRect(&layer_Rc);
		//
		m_editNode = l->CreateEditNode(&maskRc);
		m_editNode->raster_code = IPLEXT_RASTER_CODE::ALPHA_BLEND;
		l->PushEditNode(m_editNode);
		//
		move_mask = cvCreateImage(
			cvSize(maskRc.right - maskRc.left, maskRc.bottom - maskRc.top),
			IPL_DEPTH_8U,
			1);
		//

		_I8 md;
		for(int y=maskRc.top; y <= maskRc.bottom; y++){
			for(int x=maskRc.left; x <= maskRc.right; x++){
				//選択レイヤの画像をコピー
				layer_img_ext->GetPixel(x, y, &r, &g, &b, &a);

				//動かす部分のコピーを得る
				if(md = GetMaskDataPos(mask, x, y)){
					layer_img_ext->GetPixel(x, y, &r, &g, &b, &a);
					m_editNode->edit_img.SetPixel(x-maskRc.left, y-maskRc.top, r, g, b, a);
					//画像の動かす部分は透明に
				}
				else{
					//選択されていないところは透明に
					m_editNode->edit_img.SetPixel(x-maskRc.left, y-maskRc.top, 0, 0, 0, 0);
				}
				
				//mask
				SetMaskDataPos(move_mask, x-maskRc.left, y-maskRc.top, md);
			}
		}

		beforRc = maskRc;

		////画像の更新
		//UPDATE_DATA data;
		//data.isAll = false;
		//data.rect = maskRc;
		//data.update_flag = UPDATE_FLAG::UPDATE_SELECT_LAYER;
		//f->PushUpdateData(&data);
	}
}