사용자가 사용자 지정 "스탬프"를 만들어 PDF에 배치 할 수있는 양식이 있습니다. 이 양식은 pdf 첫 페이지 이미지로 표시되며 기본적으로 사용자는 자신의 도장을 원하는 화면을 클릭하여 모양이 어떻게 보이는지 미리 볼 수 있습니다. PDF 파일에 대해 걱정하지 마십시오.회전 된 텍스트의 좌표 계산 및 테두리 경계
멋진 이미지를 만들기 위해 이미지의 사본이 두 개 있습니다. 정상적인 이미지와 밝기가 감소한 이미지입니다. 저휘도 이미지를 표시하고 사용자가 마우스를 움직이면 원본 이미지의 덩어리가 표시되거나 강조 표시됩니다. 그런 다음 해당 영역에 사용자가 PDF에 넣을 텍스트를 표시합니다.
사용자는 마우스 휠을 사용하여 스크롤하려는 텍스트의 각도를 변경할 수 있습니다 (-45도에서 +45도까지).
여기 내 문제가 있습니다. 적절한 직사각형/좌표를 계산할 수 없습니다. 때로는 모든 것이 멋지게 보이고 다른 때는 (글꼴 크기가 변함에 따라) 아주 적합하지 않습니다.
는 어떻게 X를 계산합니까와 y 좌표 : 회전 된 텍스트 의 위치와 경계의 구형 패딩 10px
작품 아래의 코드와 폭에서 텍스트와 높이, 내가 크랭크 시작까지 글꼴 크기를 늘리면 모든 것이 왜곡되지 않습니다.
처음 두 개의 이미지는 작은 글꼴에 텍스트 + 경계 사각형을 표시합니다. 그것은 좋아 보인다 :
다음 이미지는 텍스트 크기가 커질수록, 내 픽셀 주위의 모든 이동 오프 다진됩니다 보여줍니다. 더 큰 텍스트에서도 너비/높이가 끝납니다.
죄송 예제 이미지는 많은 세부 사항을 표시하지 않습니다. 공유 할 수없는 실제 데이터가 있습니다.
Private Sub PanelMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) '// handles the mouse move (handler added elsehwere)
With CType(sender, PictureBox)
.Image.Dispose() '// get rid of old image
Dim b As Bitmap = _curGray.Clone '// the low brightness image as the base image
'// stamp font and text values are initiated from another form
Using g As Graphics = Graphics.FromImage(b),
f As New Font(DefaultFont.FontFamily, CSng(_stmpTools.StampTextSize), If(_stmpTools.StampBold, FontStyle.Bold, FontStyle.Regular))
Const borderWidth As Integer = 10
Const borderPadding As Integer = 5
'// measure the string
Dim szx As SizeF = g.MeasureString(_stmpTools.StampText, f, Integer.MaxValue, StringFormat.GenericDefault)
Dim strLength As Single = szx.Width
Dim strHeight As Single = szx.Height
Dim x As Single = e.X - borderWidth - borderPadding,
y As Single = e.Y
Dim w As Double, h As Double
If Math.Abs(_angle) > Double.Epsilon Then
h = CDbl(strLength) * Math.Sin(CDbl(Math.Abs(_angle)) * Math.PI/180.0F)
w = Math.Sqrt(CDbl(strLength) * CDbl(strLength) - h * h)
Else
'// its zero. so use calculated values
h = strHeight
w = strLength
End If
'// add space for the 10px border plus 5px of padding
Dim r As New Rectangle(0, 0, w, h)
r.Inflate(borderWidth + borderPadding, borderWidth + borderPadding)
h = r.Height
w = r.Width
'// keep box from moving off the left
If x < .Location.X Then
x = .Location.X
End If
'// keep box from moving off the right
If x > .Location.X + .Width - w Then
x = .Location.X + .Width - w
End If
'// I don't know, but these values work for most smaller fonts, but
'// it has got to be a fluke
If _angle > 0 Then
y = y - h + borderWidth + borderWidth
Else
y = y - borderWidth
End If
'// can't go off the top
If y < .Location.Y Then
y = .Location.Y
End If
'// can't go off the bottom
If y > .Location.Y + .Height - h Then
y = .Location.Y + .Height - h
End If
Dim rect As New Rectangle(x, y, w, h)
g.DrawImage(_curImg, rect, rect, GraphicsUnit.Pixel)
Using br As New SolidBrush(_stmpTools.StampTextColor)
RotateString(_stmpTools.StampText, _angle, e.X, e.Y, f, g, br)
End Using
'//draw bounding rectangle
Using p As New Pen(Color.Black, borderWidth)
g.DrawRectangle(p, rect)
End Using
End Using
'// set the picture box to show the new image
.Image = b
End With
End Sub
Private Sub RotateString(ByVal Text As String, ByVal angle As Integer, _
ByVal x As Integer, ByVal y As Integer, myfont As Font, mydrawing As Graphics, myColor As Brush)
Dim myMatrix As New Matrix
myMatrix.RotateAt(angle * -1, New Point(x, y)) 'Rotate drawing
mydrawing.Transform = myMatrix
mydrawing.DrawString(Text, myFont, myColor, x, y) 'Draw the text string
myMatrix.RotateAt(angle, New Point(x, y)) 'Rotate back
mydrawing.Transform = myMatrix
End Sub
나는 그리기에 관해서 최고가 아니다. 그래서 도움이 될 것입니다.
아래의 솔루션을 @LarsTech에서 사용하십시오. g.FillRectangle을 다음으로 대체했습니다.
g.DrawImage(_curImg, r, r, GraphicsUnit.Pixel)
_curImg는 밝기를 조정 한 원본 이미지의 복사본입니다. 내가 아래에서 코드를 변경하면 결국 :
두 줄을 유의하십시오. 그들은 그들이 배경 이미지로 행동하고 제안 당
Private Sub DrawStamp(g As Graphics, text As String,
f As Font, center As Point, angle As Integer, backImg As Image)
Dim s As Size = g.MeasureString(text, f).ToSize
Dim r As New Rectangle(center.X - (s.Width/2) - 16,
center.Y - (s.Height/2) - 16,
s.Width + 32,
s.Height + 32)
g.DrawImage(backImg, r, r, GraphicsUnit.Pixel)
Using m As New Matrix
m.RotateAt(angle, center)
g.Transform = m
Using p As New Pen(Color.Black, 6)
g.DrawRectangle(p, r)
End Using
Using sf As New StringFormat
sf.LineAlignment = StringAlignment.Center
sf.Alignment = StringAlignment.Center
g.DrawString(text, f, Brushes.Black, r, sf)
End Using
g.ResetTransform()
End Using
End Sub
, 지금 남아 있어요
배경을 그린 다음 회전하여 우표를 그렸습니다. 그것은 거의 작동합니다. 이 예제에서 직선은 의도 된 동작을 보여줍니다 ...그러나 나는 전체 스탬프를 배경으로 채우기를 원합니다. 옆면의 여분의 흰색은 우표의 배경으로 회전 된 것이었을 것입니다. 나는 '회색'부분이 이미지의 일부를 잘라내는 것으로 의심하기 때문에 혼란 스럽지만, 그렇지 않습니다. (불행히도 여기에 게시 할 수없는 다른 영역 위로 이동하면) 통지가 없습니다. 직사각형의 측면이 그 자체로 페인트한다는 사실을 제외하고는 비뚤어졌습니다.
잘하면 좀 더 많은 정보를 원하시면 여기
또 다른 편집 잘하면 내가 뭘하려고 오전의 더 나은 explaination입니다. 타사 PDF 뷰어를 사용하며 사용자가 이미지를 PDF에 추가 할 수 있어야합니다. 뷰어는 사용자의 마우스 클릭을 잡기 위해, 그래서 내가 다음을 수행, 내가 그것을 클릭 이벤트를 발생시킬 수 없습니다 :
- 는
- 은 PDF 뷰어를 숨기기 형태의 화면 잡아보세요
- 양식에 PictureBox 컨트롤을 추가하여 PDF 뷰어가 있던 영역을 바꿉니다.
- 내 화면을 잡으면 밝기를 줄여 이미지 복사본을 만듭니다.
- 이미지의 회색조 복사본을 표시하고 바로 그립니다. Picturebox의 이벤트에 마우스를 올려 놓은 이미지
- 나는 그림 상자에 도장을 그렸지만 그 배경을 원본 (비 조정 밝기 이미지)으로하고 싶다. 그러나 영역이 회전을 사용하여 변형 될 수 있으므로 배경 이미지를 가져올 수 없습니다. 각도를 지정하지 않으면 소스 사각형이 일치합니다. 그러나 그것의 회전, 나는 소스 이미지에서 동일한 회전 사각형을 잡을 수 없습니다.
버튼을 클릭 이벤트 : 나는 두 개의 이미지와 끝까지 그 코드 후
Dim bds As Rectangle = AxDPVActiveX1.Bounds
Dim pt As Point = AxDPVActiveX1.PointToScreen(bds.Location)
Using bit As Bitmap = New Bitmap(bds.Width, bds.Height)
Using g As Graphics = Graphics.FromImage(bit)
g.CopyFromScreen(New Point(pt.X - AxDPVActiveX1.Location.X, pt.Y - AxDPVActiveX1.Location.Y), Point.Empty, bds.Size)
End Using
_angle = 0
_curImg = bit.Clone
_curGray = Utils.CopyImageAndAdjustBrightness(bit, -100)
End Using
Dim p As New PictureBox
Utils.SetControlDoubleBuffered(p)
p.Dock = DockStyle.Fill
p.BackColor = Color.Transparent
AxDPVActiveX1.Visible = False
p.Image = _curImg.Clone
AddHandler p.MouseClick, AddressOf PanelDownMouse
AddHandler p.MouseMove, AddressOf PanelMouseMove
AddHandler p.MouseWheel, Sub(s As Object, ee As MouseEventArgs)
_angle = Math.Max(Math.Min(_angle + (ee.Delta/30), 45), -45)
PanelMouseMove(s, ee)
End Sub
AddHandler p.MouseEnter, Sub(s As Object, ee As EventArgs)
CType(s, Control).Focus()
End Sub
AxDPVActiveX1.Parent.Controls.Add(p)
. _curgray는 밝기가 조정 된 이미지이고 _curImg는 원래의 스크린 잡기입니다.
_curGray : _curImg :
mouseMove
이동 이벤트가 나의 새로운 그림 상자에 적용됩니다. 여기서 질문의 앞부분에 나오는 모든 코드가 작동합니다.
위의 코드를 사용하면 my mouseMove 이벤트가 내 그림 상자에 새로운 imageto 표시를 계속 생성합니다. 회전이 없다면, 내가 원하는 것을 거의 얻을 수 있습니다. 아래 이미지에서 스탬프의 배경이 모든 것보다 더 밝아지는 것을 확인하십시오. 파란 사각형 위에있는 부분은 약간 가볍습니다. 나는이 방법으로 시청자들의 눈을 끌기 위해이 영역을 사용하고 있습니다. 여기에 회전을 적용 할 때
그러나, 나는 원래 이미지에서 복사 할 수없는 것. 다음 이미지를 보아라, 배경은 그것과 함께 회전하지 않는다. 나는 원본 이미지에서 회전 된 사각형을 움켜 잡을 필요가있다.
http://msdn.microsoft.com/en-us/library/ms142040(v=vs.110).aspxGraphics.DrawImage()
Public Sub DrawImage (_
image As Image, _
destRect As Rectangle, _
srcRect As Rectangle, _
srcUnit As GraphicsUnit _
)
. 원본 사각형에 변형을 적용 할 수 없습니다. 기본적으로 (@larstech에서 변환을 기반으로) 회전 된 사각형에 해당하는 영역을 내 원본 이미지에서 복사하려고합니다.
이 개념을 더 명확하게 표현하는 방법을 모르겠습니다. 그래도 여전히 이해가되지 않는다면 나는 LarsTech의 대답을 최고의 대답으로 받아 들일 것이고, 나의 생각을 고칠 것이다.
당신은 사각형의 점을 변환 할 수 있습니다. 새로운 사각형 (회전 된 텍스트 주변)은 모든 X의 x = min, 모든 Y의 y = min, width = maxX-minX 및 height = maxY-minY –