Forums Neueste Beiträge
 

CopyFromScreen Bitmap als Bild speichern und Größe in Millimeter angeben

14/02/2009 - 13:05 von Tim Julsen | Report spam
Hallo,

ich erstelle mit der Methode CopyFromScreen einen Abzug eines Panels.
Anschließend erstelle ich ein neues Bitmap Objekt, bei welchen ich die Größe
in Pixel angebe.
In dieses Bitmap Objekt zeichne ich nun den Screenshot und gebe durch die
Zeilen:
g.PageUnit = GraphicsUnit.Millimeter
g.DrawImage(bmp, New Rectangle(0, 0, 30, 30))
an, dass das Bild nur 30 auf 30 groß sein soll.

Das Bild sieht dann so aus:
http://img3.imagebanana.com/img/6dk5nmog/panel.jpg

Das Panel wurde korrekt gezeichnet (in mm). Die freie Flàche stammt von der
Angabe des neu erstellten Bitmaps -> an dieser Stelle gebe ich die Werte in
px an, obwohl sie eig. in mm angegeben sein sollten.

Hier einmal der komplette Code:

Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

'Screenshot erstellen
Dim bmp As Bitmap = New Bitmap(Panel1.Width, Panel1.Height )
Using G As Graphics = Graphics.FromImage(bmp)
G.CopyFromScreen(Me.PointToScreen(Panel1.Location), New Point(0,
0), New Size(Panel1.Width, Panel1.Height))
G.Dispose()
End Using

'Bitmap oImage In welches der Screenshot gezeichnet wird
Dim b As Integer = panel1.width
Dim h As Integer = panel1.height
Dim oImage As New Bitmap(b, h) 'Angaben In px.
Using g As Graphics = Graphics.FromImage(oImage)
g.PageUnit = GraphicsUnit.Millimeter
g.DrawImage(bmp, New Rectangle(0, 0, 30, 30)) 'Angaben In mm
g.Dispose()
End Using
oImage.Save("C:\tmp.jpg")
oImage.Dispose()
End Sub
End Class

Mit folgendem Code, welchen ich aus einem Forum habe, kann man die
gewünschte Größe in mm angeben und die Funktion rechnet die Angaben um. Eine
andere Möglichkeit wàre die TwipsperPixel aus VisualBasic Compatibility.

Ich würde aber gerne auf diese Funktionen verzichten, da mir die oben
angegebene einfach 'sauberer' erscheint.

Hier einmal der Code mit den Funktionen 'GetDeviceCaps'

Public Class Form1
Private Const LOGPIXELSX As Integer = 88
Private Const LOGPIXELSY As Integer = 90

Private Declare Function GetDC Lib "user32" Alias "GetDC" _
(ByVal hWnd As IntPtr) As IntPtr

Private Declare Function GetDeviceCaps Lib "gdi32" Alias "GetDeviceCaps"
_
(ByVal hDC As IntPtr, _
ByVal nIndex As Integer) As Integer

Private nPixelsPerMMX As Single
Private nPixelsPerMMY As Single
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

'Screenshot erstellen
Dim bmp As Bitmap = New Bitmap(Panel1.Width + 2, Panel1.Height + 1)
Using G As Graphics = Graphics.FromImage(bmp)
G.CopyFromScreen(Me.PointToScreen(Panel1.Location), New Point(0,
0), New Size(Panel1.Width + 2, Panel1.Height + 1))
G.Dispose()
End Using

'Bitmap oImage In welches der Screenshot gezeichnet wird
Dim b As Integer = nPixelsPerMMX * 30 'angaben in mm
Dim h As Integer =nPixelsPerMMY * 30
Dim oImage As New Bitmap(b, h) 'Angaben In px.
Using g As Graphics = Graphics.FromImage(oImage)
g.PageUnit = GraphicsUnit.Millimeter
g.DrawImage(bmp, New Rectangle(0, 0, 30, 30)) 'Angaben In mm
g.Dispose()
End Using
oImage.Save("C:\tmp.jpg")
oImage.Dispose()
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
nPixelsPerMMX = GetDeviceCaps(GetDC(Me.Handle), LOGPIXELSX) / 25.4F
nPixelsPerMMY = GetDeviceCaps(GetDC(Me.Handle), LOGPIXELSY) / 25.4F
End Sub
End Class

Schonmal danke fürs lesen & eure Hilfe,
Gruß
Tim
 

Lesen sie die antworten

#1 Karsten Sosna
14/02/2009 - 14:04 | Warnen spam
ich erstelle mit der Methode CopyFromScreen einen Abzug eines Panels.
Anschließend erstelle ich ein neues Bitmap Objekt, bei welchen ich die
Größe in Pixel angebe.
In dieses Bitmap Objekt zeichne ich nun den Screenshot und gebe durch die
Zeilen:
g.PageUnit = GraphicsUnit.Millimeter
g.DrawImage(bmp, New Rectangle(0, 0, 30, 30))
an, dass das Bild nur 30 auf 30 groß sein soll.

Das Bild sieht dann so aus:
http://img3.imagebanana.com/img/6dk5nmog/panel.jpg

Das Panel wurde korrekt gezeichnet (in mm). Die freie Flàche stammt von
der Angabe des neu erstellten Bitmaps -> an dieser Stelle gebe ich die
Werte in px an, obwohl sie eig. in mm angegeben sein sollten.

Hier einmal der komplette Code:

Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

'Screenshot erstellen
Dim bmp As Bitmap = New Bitmap(Panel1.Width, Panel1.Height )
Using G As Graphics = Graphics.FromImage(bmp)
G.CopyFromScreen(Me.PointToScreen(Panel1.Location), New
Point(0, 0), New Size(Panel1.Width, Panel1.Height))
G.Dispose()
End Using

'Bitmap oImage In welches der Screenshot gezeichnet wird
Dim b As Integer = panel1.width
Dim h As Integer = panel1.height
Dim oImage As New Bitmap(b, h) 'Angaben In px.
Using g As Graphics = Graphics.FromImage(oImage)
g.PageUnit = GraphicsUnit.Millimeter
g.DrawImage(bmp, New Rectangle(0, 0, 30, 30)) 'Angaben In mm
g.Dispose()
End Using
oImage.Save("C:\tmp.jpg")
oImage.Dispose()
End Sub
End Class

Mit folgendem Code, welchen ich aus einem Forum habe,


Hallo Tim,
mir scheint das alles irgendwie zusammenkopiert zu sein. Sconlange nicht
mehr so was komisches gesehen, was iregendwie keinen Sinn und Verstand hat.
Beispiel:
\\\
Using G As Graphics = Graphics.FromImage(bmp)
'Do anything
G.Dispose() '<< Was soll der Aufruf?
End Using
///
Weist Du überhaupt was das Using-Konstrukt macht und wann man es einsetzt?
Kleiner Tipp,den Dispose-Aufruf kannst Du getrost löschen, das macht nàmlich
das End Using. Wichtig ist eher bmp zu disposen ober gleich in ein Using
einzubeziehen. Gleiches gilt übrigens für oImage. Also
\\\
Using BM as New Bitmap(...
Using G_BM = Graphics.FromImage(BM)
'Do Something with G_BM
End Using

Using IM as New Bitmap(...
Using G_IM = Graphics.FromImage(IM)
G_IM.DrawImage(BM, ...
End Using
End Using
End Using
///

Bevor ch zum eigentlichen komme, In Deinem Code gibt es die Deklaration:
\\\
Private Declare Function GetDC Lib "user32" Alias "GetDC" (ByVal hWnd As
IntPtr) As IntPtr
///
Und wo ist ReleaseDC???
Ach ja, braucht man nicht sehe ich gerade, man kann das ja so machen:
GetDeviceCaps(GetDC(...
Gut, dann wird halt der angeforderte DeviceContext nicht wieder freigegeben.
Früher oder spàter knallt es dann halt.

So jetzt mal eine Frage. Was soll das eigentlich werden? Irgendwie verstehe
ich es nicht. :=( Eine Bitmap ist erstmal in der Größe dimensionslos. Soll
heißen Sie hat keine Größe wie 100x100mm. Sie ist vielleich 100x100Pixel
groß, aber Pixel hat keine Einheit. Wenn Du 100Pixel auf einem Drucker
ausgibst ist das Result wohl um etliches kleiner, als wenn Du 100Pixel auf
dem Monitor ausgibst.

Also schilder mal ganz einfach was Du willst.
Gruß Scotty

Ähnliche fragen