我必須批量處理多個圖像。我必須在特定點(X,Y)放置一些文本。有一個自定義從picturebox派生的控件,允許用戶拖動文本並將其放置在所需的位置。爲自定義PictureBox控件中的不同尺寸圖像轉換點(X,Y)
有兩種類型的用於我設置PictureBoxSizeMode
不同
垂直圖像
我圖像集>PictureBoxSizeMode.Zoom;
水平
對於填充在PictureBox水平圖像I設定>PictureBoxSizeMode.StretchImage
用戶可以選擇的位置通過拖動移到該PictureBox的文本control.The原始圖像的尺寸調整爲所述控制放置文本大小(對於水平圖像),用戶將文本拖動到該圖像上。
基於圖片框的SizeMode選定點被轉換使用以下代碼
if (sizemode == 1)
{
transpoint = TranslateStretchImageMousePosition(new Point(e.X - 20, e.Y -20));
}
else if (sizemode == 2)
{
transpoint = TranslateZoomMousePosition(new Point(e.X - 20, e.Y - 20));
}
public Point TranslateStretchImageMousePosition(Point coordinates)
{
// test to make sure our image is not null
if (Image == null) return coordinates;
// Make sure our control width and height are not 0
if (Width == 0 || Height == 0) return coordinates;
// First, get the ratio (image to control) the height and width
float ratioWidth = (float)Image.Width/Width;
//MessageBox.Show(ratioWidth.ToString());
float ratioHeight = (float)Image.Height/Height;
// MessageBox.Show(ratioHeight.ToString());
// Scale the points by our ratio
float newX = coordinates.X;
float newY = coordinates.Y;
newX *= ratioWidth;
newY *= ratioHeight;
return new Point((int)newX, (int)newY);
}
public Point TranslateZoomMousePosition(Point coordinates)
{
// test to make sure our image is not null
if (Image == null) return coordinates;
// Make sure our control width and height are not 0 and our
// image width and height are not 0
if (Width == 0 || Height == 0 || Image.Width == 0 || Image.Height == 0) return coordinates;
// This is the one that gets a little tricky. Essentially, need to check
// the aspect ratio of the image to the aspect ratio of the control
// to determine how it is being rendered
float imageAspect = (float)Image.Width/Image.Height;
float controlAspect = (float)Width/Height;
float newX = coordinates.X;
float newY = coordinates.Y;
if (imageAspect > controlAspect)
{
// This means that we are limited by width,
// meaning the image fills up the entire control from left to right
float ratioWidth = (float)Image.Width/Width;
newX *= ratioWidth;
float scale = (float)Width/Image.Width;
float displayHeight = scale * Image.Height;
float diffHeight = Height - displayHeight;
diffHeight /= 2;
newY -= diffHeight;
newY /= scale;
}
else
{
// This means that we are limited by height,
// meaning the image fills up the entire control from top to bottom
float ratioHeight = (float)Image.Height/Height;
newY *= ratioHeight;
float scale = (float)Height/Image.Height;
float displayWidth = scale * Image.Width;
float diffWidth = Width - displayWidth;
diffWidth /= 2;
newX -= diffWidth;
newX /= scale;
}
return new Point((int)newX, (int)newY);
}
現在得到點之後的原始圖像內的點I必須調用主內的另一種方法形式得到近似的文字位置
point= translatemanualpoint(transpoint, img, refimgsize.Width, refimgsize.Height);
哪裏refimgsize
是原始圖像(無標度)的大小,用來放置TE XT。
private Point translatemanualpoint(Point coordinates, Bitmap Image, int Width, int Height)
{
//---------------------------------
// test to make sure our image is not null
if (Image == null) return coordinates;
// Make sure our control width and height are not 0
if (Width == 0 || Height == 0) return coordinates;
// First, get the ratio (image to control) the height and width
float ratioWidth = (float)Image.Width/Width;
float ratioHeight = (float)Image.Height/Height;
// Scale the points by our ratio
float newX = coordinates.X;
float newY = coordinates.Y;
newX *= ratioWidth;
newY *= ratioHeight;
return new Point((int)newX, (int)newY);
}
的問題是,這種方法並不accurate.When我用水平圖像作爲參考來放置文本,並且當點被轉換爲在垂直圖像的點;所述點的位置是不正確。當我使用垂直圖像作爲參考和翻譯完成水平圖像中的某一點時,會發生這種情況。
我做錯了什麼?請指教。
請讓我知道是否需要發佈控件的完整代碼。
UPDATE:
這是我想achieve.The標誌,並在下面的圖片文字手動placed.You可以看到,如何標識和文字出現在圖像大致相同的位置不同的長寬比。
UPDATE:每@ 爲彈石的意見,我採取了以下方法來找到最接近的2個邊,並使用相應的間距。
void findclosestedges(Point p)
{
//Xedge=1 -- Left Edge is closer to Point 2--Right Edge
//Finding closest Left/Right Edge
if (p.X < (ClientSize.Width - p.X))
{
LaunchOrigin.Xedge = 1;
LaunchOrigin.Xspacing = p.X;
LaunchOrigin2.closestedge.Text = " ";
LaunchOrigin2.closestedge.Text = LaunchOrigin2.closestedge.Text + " left";
}
else
{
LaunchOrigin.Xedge = 2;
LaunchOrigin.Xspacing = (ClientSize.Width - p.X);
LaunchOrigin2.closestedge.Text = " ";
LaunchOrigin2.closestedge.Text = LaunchOrigin2.closestedge.Text + " right";
}
//Finding closest Top/Bottom Edge
if (p.Y < (ClientSize.Height - p.Y))
{
LaunchOrigin.Yedge = 1;
LaunchOrigin.Yspacing =p.Y;
LaunchOrigin2.closestedge.Text = LaunchOrigin2.closestedge.Text + " top";
}
else
{
LaunchOrigin.Yedge = 2;
LaunchOrigin.Yspacing = (ClientSize.Height - p.Y);
LaunchOrigin2.closestedge.Text = LaunchOrigin2.closestedge.Text + " bottom";
}
LaunchOrigin.ewidth = Width;
LaunchOrigin.eheight = Height;
}
現在在主窗體我做以下
int wratio = img.Width/ewidth;
int hratio = img.Height/eheight;
if (Xedge == 1)
{
cpoint.X = Xspacing*wratio;
}
else
{
cpoint.X = img.Width - Xspacing * wratio;
}
if (Yedge == 1)
{
cpoint.Y = Yspacing * hratio;
}
else
{
cpoint.Y = img.Height - Yspacing*hratio;
}
我仍然沒有得到正確的定位。
我在做什麼錯?
這就是我想要實現...
UPDATE:
按@ Abion47答案我已經使用以下方法
在定製picturebox控制
Point src = e.Location;
PointF ratio = new PointF((float)src.X/Width, (float)src.Y/Height);
LaunchOrigin.ratio = ratio;
Point origin = new Point((int)(backupbit1.Width * ratio.X), (int)(backupbit1.Height * ratio.Y));
LaunchOrigin.origin = origin;
point.X = src.X - origin.X;
point.Y = src.Y - origin.Y;
在主窗口
Point pos2 = new Point((int)(ratio.X * img.Width), (int)(ratio.Y * img.Height));
cpoint.X = pos2.X - origin.X;
cpoint.Y = pos2.Y - origin.Y;
這個作品幾乎沒關係..除了右下角邊緣。
在自定義圖片框
在主窗體
我我我做錯了什麼?請指教。
UPDATE:
我所做的是計算從PictureBox控件的比例和使用這樣的比例在主要形式,以點
Point origin = new Point((int)(bitmap.Width * textratio.X), (int)(bitmap.Height * textratio.Y));
Point pos2 = new Point((int)(textratio.X * img.Width), (int)(textratio.Y * img.Height));
cpoint.X = pos2.X - (int)(origin.X);
cpoint.Y = pos2.Y - (int)(origin.Y);
徽標翻譯我也是這樣做的
Point origin = new Point((int)(worktag.Width * logoratio.X), (int)(worktag.Height * logoratio.Y));
Point logopositionpoint = new Point((int)(logoratio.X * img.Width), (int)(logoratio.Y * img.Height));
imgpoint.X = logopositionpoint.X - origin.X;
imgpoint.Y = logopositionpoint.Y - origin.Y;
這很好,直到我將文本和標誌緊密放在一起。在自定義圖片框控件中,文本和徽標正確顯示。在主窗口中,對於垂直圖像,它們顯示正常,但對於水平圖像,兩者都重疊...這裏出了什麼問題?請指點..
UPDATE
這工作well.But我如何從主窗口中的點轉換到自定義PictureBox控件(與允許拖動文本)。
我試過下面的代碼。但是,這是不是給精確定位
private Point translatetextpoint(Point mpoint,Bitmap bitmap)
{
PointF ratio = new PointF((float)LaunchOrigin.cpoint.X /LaunchOrigin.img.Width, (float)LaunchOrigin.cpoint.Y /LaunchOrigin.img.Height);
Point origin = new Point((int)(endPointPictureBox1.bit.Width * ratio.X), (int)(endPointPictureBox1.bit.Height * ratio.Y));
Point pos2 = new Point((int)(ratio.X * endPointPictureBox1.Width), (int)(ratio.Y * endPointPictureBox1
.Height));
pos2.X = pos2.X - (int)(origin.X);
pos2.Y = pos2.Y - (int)(origin.Y);
return pos2;
}
請諮詢..
嗯..爲什麼這個問題downvoted?任何意見將是有用的.. – techno
它是一個類?如果是這樣,使用ClientSize.Height高度是首選,因爲它會允許邊界..一個可能的downvote(不是我的)原因可能是缺乏研究,因爲這個問題並不完全是新的.. – TaW
@TaW我們可以繼續討論聊天http ://chat.stackoverflow.com/rooms/143591/system-drawing – techno