Пример #1
0
// a(X-x0)^2 + b(Y-y0)^2 = r^2
static void FillEllipse(IplImage* mask, int setnum, int x0, int y0, int r, int a, int b)
{
  int x,y,F,H;
  CvSize size = cvGetSize(mask);

  x = r / sqrt( (double)a );
  y = 0;
  F = -2 * sqrt( (double)a ) * r + a + 2*b;
  H = -4 * sqrt( (double)a ) * r + 2*a + b;

  while ( x > 0 ) {
	for(int i=x0 - x; i<=x0 + x; i++){
		SetMaskDataPos(mask, i, y0 + y, setnum);	
		SetMaskDataPos(mask, i, y0 - y, setnum);
	}
    if ( F < 0 ) {
      y++;
      F += 4 * b * y + 2 * b;
      H += 4 * b * y;
    } else if ( H >= 0 ) {
      x--;
      F -= 4*a*x;
      H -= 4*a*x - 2*a;
    } else {
      x--;
      y++;
      F += 4*b*y - 4*a*x + 2*b;
      H += 4*b*y - 4*a*x + 2*a;
    }
  }

}
Пример #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);
		}
	}
}
Пример #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);
		}
	}
}
Пример #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);
		}
	}
}
Пример #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;
	}
}
Пример #6
0
//四角形のマスクを作る。
void FillRectMask(IplImage* mask, uint8_t setnum, int x, int y, int width, int height)
{
	int x_ = min(x, x + width);
	int y_ = min(y, y + height);
	int width_ = abs(width);
	int height_ = abs(height);

	for(int iy = y_; iy <= y_ + height_; iy++){
		for(int ix = x_; ix <= x_ + width_; ix++){
			SetMaskDataPos(mask, ix, iy, setnum);
		}
	}
}
Пример #7
0
/*!
	線分のマスクを作る。
	@param[out] mask マスクの出力先
	@param[in] setnum 埋める値
	@param[in] start 開始位置
	@param[in] end 終了位置
*/
void LineMask(IplImage *mask, uint8_t setnum, const CvPoint2D64f *start, const CvPoint2D64f *end)
{
	float t=0.0;
	CvPoint2D64f d; //傾き
	CvPoint2D64f p;

	//end-startの傾きを計算
	SubVec2D(&d, end, start);
	float d_length = Vec2DLength(&d);
	float rev_d_length = 1.0 / d_length;
	do{
		//p = start + t*d
		ScaleVec2D(&p, t, &d);
		AddVec2D(&p, &p , start);
		//位置pにsetnum書き込み
		SetMaskDataPos(mask, p.x, p.y, setnum);

		t += rev_d_length/2.0;
	}while(t <= 1.0);
}
Пример #8
0
void SoftCircleMask(
	IplImage* dst,
	double center_x,
	double center_y,
	double r,
	uint8_t setnum,
	uint8_t alpha)
{
	assert(dst);
	assert(r > 0);

	double inv_alpha = alpha / 255.0;

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

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

	int x,y;
	uint8_t pix;
	for(y=start_y; y<=end_y; y++){
		for(x=start_x; x<=end_x; x++){
			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 < r){
				fr = 1.0 - fr/r;
				pix = (fr*fr) * (3.0-2.0*fr) * setnum*inv_alpha;
			}
			else{
				pix = 0;
			}

			SetMaskDataPos(dst, x, y, pix);
		}
	}
}
Пример #9
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);
				}
			//}
		}
	}
}
Пример #10
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);
				}
			}
		}
	}
}
Пример #11
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;
			}
		}


	}
}
Пример #12
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);
	}
}