Saving as Image

C

CyberBhai

I am using Visio 2003 ActiveX Control and Vb.Net 2003.

I have inserted some images on the drawing control, which goes beyond the
drawing page area.

My need is while saving the page as an image, may be in JPG or GIF, only the
portion which are inside the page boundary should be saved as part of the
image.

Plz. Help.
 
C

CyberBhai

I tried that with
"Dim mf As New System.Drawing.Imaging.Metafile(New
IntPtr(visiopage.Picture.Handle), False)" , but it takes the entire image
along with the part which is outside the boundary of the page.

I want to save the image which will be exactly similar to what Visio Print
Preview window generates.

Plz. help
 
A

Al Edlund

try something like this. It's unmanaged code that I use in a visio network
application (vb.net)
al


Option Explicit On

Option Strict Off

'*******************************************************************

' Program: vNetView

' Author: Albert E Edlund

' Date:

'

' Purpose: Some controls intentionally do not have the ability to natively

' do a copy to the clipboard (specifically the OWC Chart used in the ICMP

' portion of the tools) so these classes allow us to capture screens

' and controls to the clipboard or save as bitmap files

'

'*********************************************************************







Imports System

Imports System.Text

Imports System.Drawing

Imports System.Drawing.Image

Imports System.Drawing.Bitmap

Imports System.Drawing.Imaging

Imports System.Drawing.Imaging.ImageFormat

Imports System.Runtime.InteropServices

Imports Microsoft.Practices.EnterpriseLibrary.ExceptionHandling



Friend Class GDI32



<DllImport("GDI32")> _

Public Shared Function BitBlt(ByVal handleDeviceContextDest As IntPtr, _

ByVal intXDest As Integer, _

ByVal intYDest As Integer, _

ByVal intWidth As Integer, _

ByVal intHeight As Integer, _

ByVal handleDeviceContextSrc As IntPtr, _

ByVal intXSrc As Integer, _

ByVal intYSrc As Integer, _

ByVal intRop As Integer) _

As Boolean

End Function

<DllImport("GDI32")> _

Public Shared Function CreateCompatibleBitmap(ByVal handleDeviceContext As
IntPtr, _

ByVal intWidth As Integer, _

ByVal intHeight As Integer) _

As Integer

End Function

<DllImport("GDI32")> _

Public Shared Function CreateCompatibleDC(ByVal handleDeviceContext As
IntPtr) As Integer

End Function

<DllImport("GDI32")> _

Public Shared Function DeleteDC(ByVal handleDeviceContext As IntPtr) As
Boolean

End Function

<DllImport("GDI32")> _

Public Shared Function DeleteObject(ByVal intObject As Integer) As Boolean

End Function

<DllImport("GDI32")> _

Public Shared Function GetDeviceCaps(ByVal handleDeviceContext As IntPtr, _

ByVal nIndex As Integer) _

As Integer

End Function

<DllImport("GDI32")> _

Public Shared Function SelectObject(ByVal handleDeviceContext As IntPtr, _

ByVal hgdiobj As Integer) _

As Integer

End Function

End Class



Friend Class User32

Public Structure LPRECT

Public left As Integer

Public top As Integer

Public right As Integer

Public bottom As Integer

End Structure



<DllImport("User32")> _

Public Shared Function GetDesktopWindow() _

As IntPtr

End Function



<DllImport("User32")> _

Public Shared Function CreateCompatibleDC(ByVal handleWin As IntPtr) _

As IntPtr

End Function





<DllImport("User32")> _

Public Shared Function GetWindowDC(ByVal handleWin As IntPtr) _

As IntPtr

End Function

<DllImport("User32")> _

Public Shared Function ReleaseDC(ByVal handleWin As IntPtr, _

ByVal handleDC As Integer) _

As IntPtr

End Function

' the clipboard stuff

<DllImport("User32")> _

Public Shared Function OpenClipboard(ByVal handleWin As IntPtr) _

As IntPtr

End Function

<DllImport("User32")> _

Public Shared Function EmptyClipboard() _

As IntPtr

End Function

<DllImport("User32")> _

Public Shared Function CloseClipboard() _

As IntPtr

End Function

<DllImport("User32")> _

Public Shared Function SetClipboardData(ByVal intFormat As Integer, _

ByVal handleWin As IntPtr) _

As IntPtr

End Function

<DllImport("User32")> _

Public Shared Function GetWindowRect(ByVal handleWin As IntPtr, _

ByRef lpRect As LPRECT) _

As IntPtr

End Function

End Class



Public Class ScreenScrape





'Dim clsSS As New ScreenScrape

'clsSS.CaptureWindowToClipboard(ChartSpace1)

'clsSS = Nothing

' some controls don't support capturing to clipboard

Public Sub CaptureWindowToClipboard(ByVal objControl As
System.Windows.Forms.Control)

Dim sbParameters As New StringBuilder

Dim intMargin As Integer = 2

Dim intLeft As Integer = 0

Dim intTop As Integer = 0

Dim intRight As Integer = 0

Dim intBottom As Integer = 0

Dim rctControl As User32.LPRECT

Dim intReturn As Integer = Nothing

Dim handleDesktop As IntPtr = User32.GetDesktopWindow

Dim handleDCSrc As IntPtr = Nothing

Dim handleDCDest As IntPtr = Nothing

Dim handleBitMap As IntPtr = Nothing

Dim handleControl As IntPtr = Nothing

Try

objControl.Focus()

handleControl = objControl.Handle

User32.GetWindowRect(handleControl, rctControl)

With rctControl

intLeft = .left - intMargin

intTop = .top - intMargin

intRight = .right + intMargin

intBottom = .bottom + intMargin

End With

handleDCSrc = User32.GetWindowDC(handleDesktop)

If handleDCSrc = Nothing Then MsgBox("GetWindowDC Failed")

handleDCDest = GDI32.CreateCompatibleDC(handleDCSrc)

If handleDCDest = Nothing Then MsgBox("CreateCompatibleDC Failed")

' need handle for source and capabilities (width and height)

handleBitMap = GDI32.CreateCompatibleBitmap(handleDCSrc, _

intRight - intLeft, _

intBottom - intTop)

If handleBitMap = Nothing Then MsgBox("CreateCompatibleBitmap Failed")

intReturn = GDI32.SelectObject(handleDCDest, handleBitMap)

If intReturn = Nothing Then MsgBox("SelectObject Failed")

intReturn = GDI32.BitBlt(handleDCDest, _

0, _

0, _

intRight - intLeft, _

intBottom - intTop, _

handleDCSrc, _

intLeft, _

intTop, _

&HCC0020)

'sbParameters.Append("handleDesktop " & handleDesktop.ToString & vbCrLf)

'sbParameters.Append("handleDCSrc " & handleDCSrc.ToString & vbCrLf)

'sbParameters.Append("handleDCDest " & handleDCDest.ToString & vbCrLf)

'sbParameters.Append("handleControl " & handleControl.ToString & vbCrLf)

'sbParameters.Append("handleBitMap " & handleBitMap.ToString & vbCrLf)

'sbParameters.Append("Right " & intRight.ToString & vbCrLf)

'sbParameters.Append("Left " & intLeft.ToString & vbCrLf)

'sbParameters.Append("Bottom " & intBottom.ToString & vbCrLf)

'sbParameters.Append("Top " & intTop.ToString & vbCrLf)

'MsgBox(sbParameters.ToString)

If intReturn = 0 Then MsgBox("BitBlT failed")



User32.OpenClipboard(handleControl)

User32.EmptyClipboard()

User32.SetClipboardData(2&, handleBitMap)

User32.CloseClipboard()

' MSDN promises dire consequences if we do not release what we had

Cleanup(handleBitMap, _

handleDCSrc, _

handleDCDest)

Catch err As Exception

Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only
Policy")

If (rethrow) Then

Throw

End If

End Try

End Sub

'Dim clsSS As New ScreenScrape

'clsSS.CaptureScreenToFile("c:\screen.bmp", imageformat.bmp)

' in case we want to save the screen as a bitmap

Public Sub CaptureScreenToFile(ByVal strFileName As String, _

ByVal myFormat As ImageFormat)

Dim handleDCSrc As Integer

Dim handleDCDest As Integer

Dim handleBitMap As Integer

Try

handleDCSrc = User32.GetWindowDC(User32.GetDesktopWindow())

handleDCDest = GDI32.CreateCompatibleDC(handleDCSrc)

handleBitMap = GDI32.CreateCompatibleBitmap(handleDCSrc, _

GDI32.GetDeviceCaps(handleDCSrc, 8), _

GDI32.GetDeviceCaps(handleDCSrc, 10))

GDI32.SelectObject(handleDCDest, handleBitMap)

GDI32.BitBlt(handleDCDest, _

0, _

0, _

GDI32.GetDeviceCaps(handleDCSrc, 8), _

GDI32.GetDeviceCaps(handleDCSrc, 10), _

handleDCSrc, _

0, _

0, _

&HCC0020)



' save the screen image

SaveImageAs(handleBitMap, _

strFileName, _

myFormat)

' again release what we had

Cleanup(handleBitMap, _

handleDCSrc, _

handleDCDest)

Catch err As Exception

Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only
Policy")

If (rethrow) Then

Throw

End If

End Try

End Sub







Private Sub SaveImageAs(ByVal handleBitMap As Integer, _

ByVal strFileName As String, _

ByVal myFormat As System.Drawing.Imaging.ImageFormat)

Try

Dim BitMap As Image = New Bitmap(Image.FromHbitmap(New
IntPtr(handleBitMap)), _

Image.FromHbitmap(New IntPtr(handleBitMap)).Width, _

Image.FromHbitmap(New IntPtr(handleBitMap)).Height)

BitMap.Save(strFileName, myFormat)

Catch err As Exception

Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only
Policy")

If (rethrow) Then

Throw

End If

End Try

End Sub

Private Sub Cleanup(ByVal handleBitMap As Integer, _

ByVal handleDeviceContextSrc As Integer, _

ByVal handleDeviceContextDest As Integer)

User32.ReleaseDC(User32.GetDesktopWindow(), handleDeviceContextSrc)

GDI32.DeleteDC(handleDeviceContextDest)

GDI32.DeleteObject(handleBitMap)

End Sub

End Class
 
C

CyberBhai

Though I am able to understand what it does, I am not able to incorporate it.

Let me once again clarify what I need.

My print Preview works fine except one particular instance. When someone
puts objects outside the boundary of the drawing space, the Picture property
of the page takes the entire shot of everything that is there on the page
including objects present outside the drawing space or page outline.

I need to only get the portions which are inside the page boundary or inside
the drawing space.

I very badly need this as it seems odd to have images which have got images
outside the scope of a page

Plz. help.
 
A

Al Edlund

The class allows you to grab whatever a control is displaying using
something like this by sending it the control name. You just have to add
what you want the visio drawing control to look like (adjust the window to
the image size you want).

Private Sub cmdCopyChart_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles cmdCopyChart.Click

Dim clsSS As New ScreenScrape

Try

clsSS.CaptureWindowToClipboard(AxChartSpace1)

clsSS = Nothing

Catch err As Exception

Dim rethrow As Boolean = ExceptionPolicy.HandleException(err, "Log Only
Policy")

If (rethrow) Then

Throw

End If

End Try

End Sub
 
C

CyberBhai

Hi Al,
Thanx a lot. I have got the screenshot from the activex control.
But, still there are problems is to be solved.
When I open a document file in the control, I load it at 100% of zoom.
Depending on the paper size, the control either displays the scrollbar or
hides it. So, when I get the screenshot, it only gets a part of it.

Plz. help.
 
A

Al Edlund

The screen grabber should save what is in the 'window' that is visible. It
sounds like what you are describing is a drawing that is larger than the
selected window. I usually use something like this to make sure it is all
visible.
visWindow.ViewFit = visFitPage

System.Windows.Forms.Application.DoEvents()

al
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top