Click here to Skip to main content
15,881,882 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
How to resize the image inside the PictureBox?

I mean not to resize the PictureBox but to resize the picture in it.
Posted

1 solution

Here's a class that I cobbled together over the last few years from various sources, and heavily modified, that you can use to do image size scaling (using stretchblit), jpeg compression tweaking, take desktop screenshots, ect. You will want to use the:

VB
Public Function ResizeImage(ByVal sourceBitmap As Bitmap, ByVal newWidth As Integer, ByVal newHeight As Integer, Optional ByVal bpp As Short = 24) As Image


method.

code:

VB
Option Strict On

Imports System
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.IO

Public Class clsGDI_Graphics

    ' vbPaletteMode(s):
    ' vbPaletteModeHalfTone     = 0 - (Default) Use the Halftone palette.
    ' vbPaletteModeUseZOrder    = 1 - Use the palette from the topmost control that has a palette.
    ' vbPaletteModeCustom       = 2 - Use the palette specified in the "Palette" property.
    ' vbPaletteModeContainer    = 3 - Use the container's palette for containers that support ambient Palette property. Applies to UserControls only.
    ' vbPaletteModeNone         = 4 - Do not use any palette. Applies to UserControls only.
    ' vbPaletteModeObject       = 5 - Use the ActiveX designers palette. (Applies only to ActiveX designers which contain a palette.)
    Const STRETCHMODE As Integer = 4 ' vbPaletteModeNone

    Shared BI_RGB As UInteger = 0
    Shared DIB_RGB_COLORS As UInteger = 0

    ' Creates an Image object containing a screen shot of the entire desktop
    Public Function CaptureScreen() As Image
        Return CaptureWindow(User32.GetDesktopWindow())
    End Function 'CaptureScreen

    Public Function CaptureScreenAndResize(ByVal newWidth As Integer, ByVal newHeight As Integer) As Image
        Return CaptureWindowAndResize(User32.GetDesktopWindow(), newWidth, newHeight)
    End Function

    Public Function CaptureWindowAndResize(ByVal handle As IntPtr, ByVal newWidth As Integer, ByVal newHeight As Integer, _
                                           Optional mode As Int32 = GDI32.StretchBltMode.STRETCH_DELETESCANS) As Image

        ' get te hDC of the target window
        Dim hdcSrc As IntPtr = User32.GetWindowDC(handle)
        ' get the size
        Dim windowRect As New User32.RECT()
        User32.GetWindowRect(handle, windowRect)
        Dim width As Integer = windowRect.right - windowRect.left
        Dim height As Integer = windowRect.bottom - windowRect.top
        ' create a device context we can copy to
        Dim hdcDest As IntPtr = GDI32.CreateCompatibleDC(hdcSrc)
        ' create a bitmap we can copy it to,
        ' using GetDeviceCaps to get the width/height
        Dim hBitmap As IntPtr = GDI32.CreateCompatibleBitmap(hdcSrc, width, height)
        ' select the bitmap object
        Dim hOld As IntPtr = GDI32.SelectObject(hdcDest, hBitmap)
        ' SetStretchBltMode to handle image artifacts
        GDI32.SetStretchBltMode(hdcDest, gdi32.StretchBltMode.STRETCH_HALFTONE)
        ' StretchBlt over
        GDI32.StretchBlt(hdcDest, 0, 0, newWidth, newHeight, hdcSrc, 0, 0, width, height, TernaryRasterOperations.SRCCOPY)
        ' restore selection
        GDI32.SelectObject(hdcDest, hOld)
        ' clean up 
        GDI32.DeleteDC(hdcDest)
        User32.ReleaseDC(handle, hdcSrc)

        ' get a .NET image object for it
        Dim img As Image = Image.FromHbitmap(hBitmap)
        ' free up the Bitmap object
        GDI32.DeleteObject(hBitmap)

        Return img
    End Function

    ' Creates an Image object containing a screen shot of a specific window
    Public Function CaptureWindow(ByVal handle As IntPtr) As Image
        ' get te hDC of the target window
        Dim hdcSrc As IntPtr = User32.GetWindowDC(handle)
        ' get the size
        Dim windowRect As New User32.RECT()
        User32.GetWindowRect(handle, windowRect)
        Dim width As Integer = windowRect.right - windowRect.left
        Dim height As Integer = windowRect.bottom - windowRect.top
        ' create a device context we can copy to
        Dim hdcDest As IntPtr = GDI32.CreateCompatibleDC(hdcSrc)
        ' create a bitmap we can copy it to,
        ' using GetDeviceCaps to get the width/height
        Dim hBitmap As IntPtr = GDI32.CreateCompatibleBitmap(hdcSrc, width, height)
        ' select the bitmap object
        Dim hOld As IntPtr = GDI32.SelectObject(hdcDest, hBitmap)
        ' bitblt over
        GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY)
        ' restore selection
        GDI32.SelectObject(hdcDest, hOld)
        ' clean up 
        GDI32.DeleteDC(hdcDest)
        User32.ReleaseDC(handle, hdcSrc)

        ' get a .NET image object for it
        Dim img As Image = Image.FromHbitmap(hBitmap)
        ' free up the Bitmap object
        GDI32.DeleteObject(hBitmap)

        Return img
    End Function 'CaptureWindow

    ' For CaptureWindowFromDevice
    Private Declare Function CreateCompatibleDC Lib "GDI32" (ByVal hDC As Integer) As Integer
    Private Declare Function CreateCompatibleBitmap Lib "GDI32" (ByVal hDC As Integer, ByVal nWidth As Integer, ByVal nHeight As Integer) As Integer
    Private Declare Function GetDeviceCaps Lib "gdi32" Alias "GetDeviceCaps" (ByVal hdc As Integer, ByVal nIndex As Integer) As Integer
    Private Declare Function SelectObject Lib "GDI32" (ByVal hDC As Integer, ByVal hObject As Integer) As Integer
    Private Declare Function BitBlt Lib "GDI32" (ByVal srchDC As Integer, ByVal srcX As Integer, ByVal srcY As Integer, ByVal srcW As Integer, ByVal srcH As Integer, ByVal desthDC As Integer, ByVal destX As Integer, ByVal destY As Integer, ByVal op As Integer) As Integer
    Private Declare Function DeleteDC Lib "GDI32" (ByVal hDC As Integer) As Integer
    Private Declare Function DeleteObject Lib "GDI32" (ByVal hObj As Integer) As Integer

    Const SRCCOPY As Integer = &HCC0020

    ' Creates an Image object containing a screen shot of a specific window
    Public Function CaptureWindowFromPrimaryDevice() As Image
        Dim hSDC, hMDC As Integer
        Dim hBMP, hBMPOld As Integer
        Dim FW, FH As Integer
        Dim r As Integer

        hSDC = GDI32.CreateDC(enumDisplayDevicesForPrimary, "", "", "")
        hMDC = CreateCompatibleDC(hSDC)

        FW = GetDeviceCaps(hSDC, 8)
        FH = GetDeviceCaps(hSDC, 10)
        hBMP = CreateCompatibleBitmap(hSDC, FW, FH)

        hBMPOld = SelectObject(hMDC, hBMP)
        r = BitBlt(hMDC, 0, 0, FW, FH, hSDC, 0, 0, 13369376)
        hBMP = SelectObject(hMDC, hBMPOld)

        r = DeleteDC(hSDC)
        r = DeleteDC(hMDC)

        CaptureWindowFromPrimaryDevice = Image.FromHbitmap(New IntPtr(hBMP))
        DeleteObject(hBMP)
    End Function 'CaptureWindow

    ' Captures a screen shot of a specific window, and saves it to a file
    Public Sub CaptureWindowToFile(ByVal handle As IntPtr, ByVal filename As String, ByVal format As ImageFormat)
        Dim img As Image = CaptureWindow(handle)
        img.Save(filename, format)
    End Sub 'CaptureWindowToFile

    ' Captures a screen shot of the entire desktop, and saves it to a file
    Public Sub CaptureScreenToFile(ByVal filename As String, ByVal format As ImageFormat)
        Dim img As Image = CaptureScreen()
        img.Save(filename, format)
    End Sub 'CaptureScreenToFile

    Public Function ByteArrayToImage(ByVal ByteArray() As Byte) As Image
        Dim ImageStream As MemoryStream

        Try
            If ByteArray.GetUpperBound(0) > 0 Then
                ImageStream = New MemoryStream(ByteArray)
                ByteArrayToImage = Image.FromStream(ImageStream)
            Else
                ByteArrayToImage = Nothing
            End If
        Catch ex As Exception
            ByteArrayToImage = Nothing
        End Try

    End Function

    Public Function ImageToByteArray(ByRef NewImage As Image, ByRef ByteArray() As Byte, Optional ByVal errMsg As String = "") As Boolean
        Dim ImageStream As MemoryStream
        ImageToByteArray = True

        Try
            ReDim ByteArray(0)
            If NewImage IsNot Nothing Then
                ImageStream = New MemoryStream
                NewImage.Save(ImageStream, ImageFormat.Jpeg)
                ByteArray = ImageStream.GetBuffer
            End If
        Catch ex As Exception
            ImageToByteArray = False
            errMsg = ex.Message
        End Try

    End Function

    ' .biSizeImage = Abs(.biHeight) * ByteAlignOnWord(.biBitCount, .biWidth)
    Private Function ByteAlignOnWord(ByVal BitDepth As Byte, ByVal Width As Long) As Long
        ' function to align any bit depth on dWord boundaries
        ByteAlignOnWord = (((Width * BitDepth) + &H1F&) And Not &H1F&) \ &H8&
    End Function

    Public Function ResizeImage(ByVal sourceBitmap As Bitmap, ByVal newWidth As Integer, _
                                ByVal newHeight As Integer, Optional ByVal bpp As Short = 24) As Image

        ' (1) Convert our Bitmap into a GDI hbitmap (ie. copy unmanaged->managed)
        Dim sourceWidth As Integer = sourceBitmap.Width
        Dim sourceHeight As Integer = sourceBitmap.Height
        Dim hbm As IntPtr = sourceBitmap.GetHbitmap()

        ' (2) Create the canvas bitmap.
        ' "BITMAPINFO" is an interop-struct which we define below.
        Dim bmi As New BITMAPINFO()
        bmi.biSize = 40
        bmi.biWidth = newWidth
        bmi.biHeight = newHeight
        bmi.biPlanes = 1
        bmi.biBitCount = bpp
        bmi.biCompression = BI_RGB
        bmi.biSizeImage = CUInt(Math.Abs(bmi.biHeight) * ByteAlignOnWord(CByte(bmi.biBitCount), bmi.biWidth))
        bmi.biXPelsPerMeter = 1000000
        bmi.biYPelsPerMeter = 1000000

        ' Now create the DIBSection bitmap "hbm0"
        Dim bits0 As IntPtr ' It returns a pointer to the raw bits that make up the bitmap.
        Dim hbm0 As IntPtr = GDI32.CreateDIBSection(IntPtr.Zero, bmi, DIB_RGB_COLORS, bits0, IntPtr.Zero, 0)
        '
        ' (3): use GDI's SetStretchBltMode function to copy from original hbitmap into altered bitmap
        ' Obtain the DC for the screen
        Dim sdc As IntPtr = GDI32.GetDC(IntPtr.Zero)

        ' Next, create a DC for the original hbitmap
        Dim hdc As IntPtr = GDI32.CreateCompatibleDC(sdc)
        GDI32.SelectObject(hdc, hbm)

        ' and create a DC for the altered hbitmap
        Dim hdc0 As IntPtr = GDI32.CreateCompatibleDC(sdc)
        GDI32.SelectObject(hdc0, hbm0)

        ' Now we do our StretchBlt:
        GDI32.SetStretchBltMode(hdc0, GDI32.StretchBltMode.STRETCH_ORSCANS)
        GDI32.StretchBlt(hdc0, 0, 0, newWidth, newHeight, hdc, 0, 0, sourceWidth, sourceHeight, TernaryRasterOperations.SRCCOPY)

        ' Get the results
        Dim finishedImage As System.Drawing.Image = System.Drawing.Image.FromHbitmap(hbm0)

        ' Some cleanup.
        GDI32.DeleteDC(hdc)
        GDI32.DeleteDC(hdc0)

        User32.ReleaseDC(IntPtr.Zero, sdc)

        GDI32.DeleteObject(hbm)
        GDI32.DeleteObject(hbm0)

        Return finishedImage
    End Function

    <flags()> _
    Enum DisplayDeviceStateFlags As Integer
        ''' <summary>The device is part of the desktop.</summary>
        AttachedToDesktop = &H1
        MultiDriver = &H2
        ''' <summary>The device is part of the desktop.</summary>
        PrimaryDevice = &H4
        ''' <summary>Represents a pseudo device used to mirror application drawing for remoting or other purposes.</summary>
        MirroringDriver = &H8
        ''' <summary>The device is VGA compatible.</summary>
        VGACompatible = &H16
        ''' <summary>The device is removable; it cannot be the primary display.</summary>
        Removable = &H20
        ''' <summary>The device has more display modes than its output devices support.</summary>
        ModesPruned = &H8000000
        Remote = &H4000000
        Disconnect = &H2000000
    End Enum

    <structlayout(layoutkind.sequential,> _
    Public Structure DISPLAY_DEVICE
        <marshalas(unmanagedtype.u4)> _
        Public cb As Integer
        <marshalas(unmanagedtype.byvaltstr,> _
        Public DeviceName As String
        <marshalas(unmanagedtype.byvaltstr,> _
        Public DeviceString As String
        <marshalas(unmanagedtype.u4)> _
        Public StateFlags As DisplayDeviceStateFlags
        <marshalas(unmanagedtype.byvaltstr,> _
        Public DeviceID As String
        <marshalas(unmanagedtype.byvaltstr,> _
        Public DeviceKey As String
    End Structure

    <dllimport("user32.dll")> _
        Private Shared Function EnumDisplayDevices(ByVal lpDevice As String, ByVal iDevNum As UInteger, ByRef lpDisplayDevice As DISPLAY_DEVICE, ByVal dwFlags As UInteger) As Boolean
    End Function

    Public Function enumDisplayDevicesForPrimary() As String
        Dim device As DISPLAY_DEVICE = New DISPLAY_DEVICE()
        device.cb = Marshal.SizeOf(device)

        enumDisplayDevicesForPrimary = ""

        Try
            Dim id As UInteger = 0
            While enumDisplayDevices(Nothing, id, device, 0)

                If device.StateFlags.ToString.Contains("PrimaryDevice") Then
                    Return device.DeviceName
                End If

                device.cb = Marshal.SizeOf(device)

                ' Run EnumDisplayDevices a second time to get access to connected monitor
                enumDisplayDevices(device.DeviceName, 0, device, 0)

                device.cb = Marshal.SizeOf(device)
                id = CUInt(id + 1)

            End While
        Catch ex As Exception
            Console.WriteLine([String].Format("{0}", ex.ToString()))
        End Try
    End Function

    Private Class JpegTools
        Private codecs As ImageCodecInfo() = ImageCodecInfo.GetImageEncoders()
        Private quality As Long

        Public ici As ImageCodecInfo = Nothing
        Public ep As New EncoderParameters()
        Public compressionRatio As Long

        Public Sub new(ByVal _compressionRatio As Long, Optional ByRef errMsg As String = "")

            compressionRatio    = _compressionRatio
            If compressionRatio < 0 then compressionRatio = 0
            If compressionRatio > 100 then compressionRatio = 100
            quality             = (100 - compressionRatio)

            Try
                For Each codec As ImageCodecInfo In codecs
                    If codec.MimeType = "image/jpeg" Then
                        ici = codec
                    End If
                Next

                ep.Param(0) = New EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality)
            Catch ex As Exception
                errMsg = ex.Message
            End Try
        End Sub
    End Class

    Private JpgTools As JpegTools

    ' Save an Image() to a jpeg file and specify the compression % (Valid values for compressionRatio are 0 - 100)
    Public Function SaveImgToFile(ByRef img As Image, ByVal fullPathWithFileName As String, ByVal compressionRatio As Long, _
                                  Optional ByRef errMsg As String = "") As Boolean

        If JpgTools Is Nothing Then JpgTools = New JpegTools(compressionRatio, errMsg)
        If JpgTools.compressionRatio <> compressionRatio then JpgTools = New JpegTools(compressionRatio, errMsg)
        If errMsg <> "" then Return False

        Try
            img.Save(fullPathWithFileName, JpgTools.ici, JpgTools.ep)
        Catch ex As Exception
            errMsg = ex.Message
            Return False
        End Try
        
        Return True
    End Function

    ' Helper class containing Gdi32 API functions
    Public Class GDI32

        Public Shared SRCCOPY As Integer = &HCC0020
        ' BitBlt dwRop parameter
        <dllimport("user32.dll")> _
        Public Shared Function GetDC(ByVal hwnd As IntPtr) As IntPtr
        End Function

        <system.runtime.interopservices.dllimport("gdi32.dll")> _
        Public Shared Function CreateDIBSection(ByVal hdc As IntPtr, _
                                        ByRef bmi As BITMAPINFO, ByVal Usage As UInteger, ByVal bits As IntPtr, _
                                        ByVal hSection As IntPtr, ByVal dwOffset As UInteger) As IntPtr
        End Function

        <dllimport("gdi32.dll")> _
        Public Shared Function BitBlt(ByVal hObject As IntPtr, ByVal nXDest As Integer, ByVal nYDest As Integer, _
                                        ByVal nWidth As Integer, ByVal nHeight As Integer, ByVal hObjectSource As IntPtr, _
                                        ByVal nXSrc As Integer, ByVal nYSrc As Integer, ByVal dwRop As Integer) As Boolean
        End Function

        <dllimport("gdi32.dll")> _
        Public Shared Function StretchBlt(ByVal hdcDest As IntPtr, _
                                       ByVal nXOriginDest As Integer, _
                                       ByVal nYOriginDest As Integer, _
                                       ByVal nWidthDest As Integer, _
                                       ByVal nHeightDest As Integer, _
                                       ByVal hdcSrc As IntPtr, _
                                       ByVal nXOriginSrc As Integer, _
                                       ByVal nYOriginSrc As Integer, _
                                       ByVal nWidthSrc As Integer, _
                                       ByVal nHeightSrc As Integer, _
                                       ByVal dwRop As TernaryRasterOperations) As Boolean
        End Function

        Public Enum StretchBltMode As Integer
             STRETCH_ANDSCANS = 1
             STRETCH_ORSCANS = 2
             STRETCH_DELETESCANS = 3
             STRETCH_HALFTONE = 4
        End Enum

        <dllimport("gdi32.dll")> _
        Public Shared Function SetStretchBltMode(hdc As IntPtr, iStretchMode As StretchBltMode) As Boolean
        End Function

        <dllimport("gdi32.dll")> _
        Public Shared Function CreateBitmap(ByVal nWidth As Integer, ByVal nHeight As Integer, _
                                             ByVal cPlanes As UInteger, ByVal cBitsPerPel As UInteger, _
                                             ByVal lpvBits As IntPtr) As IntPtr
        End Function

        <dllimport("gdi32.dll")> _
        Public Shared Function CreateDC(ByVal lpDriverName As String, ByVal lpDeviceName As String, _
                                        ByVal lpOutput As String, ByVal lpInitData As String) As Integer
        End Function

        <dllimport("gdi32.dll")> _
        Public Shared Function GetDeviceCaps(ByVal hdc As Integer, ByVal nIndex As Integer) As Integer
        End Function

        <dllimport("gdi32.dll")> Public Shared Function CreateCompatibleBitmap(ByVal hDC As IntPtr, _
                        ByVal nWidth As Integer, ByVal nHeight As Integer) As IntPtr
        End Function

        <dllimport("gdi32.dll")> Public Shared _
        Function CreateCompatibleDC(ByVal hDC As IntPtr) As IntPtr
        End Function

        <dllimport("gdi32.dll")> Public Shared _
        Function DeleteDC(ByVal hDC As IntPtr) As Boolean
        End Function

        <dllimport("gdi32.dll")> Public Shared _
        Function DeleteObject(ByVal hObject As IntPtr) As Boolean
        End Function

        <dllimport("gdi32.dll")> Public Shared _
        Function SelectObject(ByVal hDC As IntPtr, ByVal hObject As IntPtr) As IntPtr
        End Function

    End Class 'GDI32

    ' Helper class containing User32 API functions
    Private Class User32
        <structlayout(layoutkind.sequential)> _
        Public Structure RECT
            Public left As Integer
            Public top As Integer
            Public right As Integer
            Public bottom As Integer
        End Structure 'RECT

        <dllimport("user32.dll",> _
        Public Shared Function OpenInputDesktop(ByVal dwFlags As UInteger, _
                                                ByVal fInherit As Boolean, _
                                                ByVal dwDesiredAccess As UInteger) As IntPtr
        End Function

        <dllimport("user32.dll")> Public Shared _
        Function GetDesktopWindow() As IntPtr
        End Function

        <dllimport("user32.dll")> Public Shared _
        Function GetWindowDC(ByVal hWnd As IntPtr) As IntPtr
        End Function

        <dllimport("user32.dll")> Public Shared _
        Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As IntPtr
        End Function

        <dllimport("user32.dll")> Public Shared _
        Function GetWindowRect(ByVal hWnd As IntPtr, ByRef rect As RECT) As IntPtr
        End Function

        <dllimport("user32.dll")> _
        Public Shared Function InvalidateRect(ByVal hwnd As IntPtr, ByVal rect As IntPtr, _
                                              ByVal bErase As Integer) As Integer
        End Function
    End Class 'User32

    ''' <summary>
    '''     Specifies a raster-operation code. These codes define how the color data for the
    '''     source rectangle is to be combined with the color data for the destination
    '''     rectangle to achieve the final color.
    ''' </summary>
    Enum TernaryRasterOperations As UInteger
        ''' <summary>dest = source</summary>
        SRCCOPY = &HCC0020
        ''' <summary>dest = source OR dest</summary>
        SRCPAINT = &HEE0086
        ''' <summary>dest = source AND dest</summary>
        SRCAND = &H8800C6
        ''' <summary>dest = source XOR dest</summary>
        SRCINVERT = &H660046
        ''' <summary>dest = source AND (NOT dest)</summary>
        SRCERASE = &H440328
        ''' <summary>dest = (NOT source)</summary>
        NOTSRCCOPY = &H330008
        ''' <summary>dest = (NOT src) AND (NOT dest)</summary>
        NOTSRCERASE = &H1100A6
        ''' <summary>dest = (source AND pattern)</summary>
        MERGECOPY = &HC000CA
        ''' <summary>dest = (NOT source) OR dest</summary>
        MERGEPAINT = &HBB0226
        ''' <summary>dest = pattern</summary>
        PATCOPY = &HF00021
        ''' <summary>dest = DPSnoo</summary>
        PATPAINT = &HFB0A09
        ''' <summary>dest = pattern XOR dest</summary>
        PATINVERT = &H5A0049
        ''' <summary>dest = (NOT dest)</summary>
        DSTINVERT = &H550009
        ''' <summary>dest = BLACK</summary>
        BLACKNESS = &H42
        ''' <summary>dest = WHITE</summary>
        WHITENESS = &HFF0062
        ''' <summary>
        ''' Capture window as seen on screen.  This includes layered windows 
        ''' such as WPF windows with AllowsTransparency="true"
        ''' </summary>
        CAPTUREBLT = &H40000000
    End Enum

    <system.runtime.interopservices.structlayout(system.runtime.interopservices.layoutkind.sequential)> _
    Public Structure BITMAPINFO
        Public biSize As UInteger
        Public biWidth As Integer, biHeight As Integer
        Public biPlanes As Short, biBitCount As Short
        Public biCompression As UInteger, biSizeImage As UInteger
        Public biXPelsPerMeter As Integer, biYPelsPerMeter As Integer
        Public biClrUsed As UInteger, biClrImportant As UInteger
        <system.runtime.interopservices.marshalas(system.runtime.interopservices.unmanagedtype.byvalarray,> _
        Public cols As UInteger()
    End Structure

    Private Shared Function MAKERGB(ByVal r As Integer, ByVal g As Integer, ByVal b As Integer) As UInteger
        Return CUInt(b And 255) Or CUInt((r And 255) << 8) Or CUInt((g And 255) << 16)
    End Function
End Class 'ScreenCapture 


hope this helps.

- Pete
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900