Results 1 to 10 of 10

Thread: Saving a Scanned Image

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Nov 2008
    Posts
    233

    Saving a Scanned Image

    I have Parent and Child Form

    I have a button to save on the child form, which uses the code below, all works fine.

    Code:
    Private Sub menuItemSaveAs_Click(ByVal sender As Object, ByVal e As System.EventArgs)
                Gdip.SaveDIBAs(Me.Text, bmpptr, pixptr)
            End Sub
    Which then uses code below, located in my GDIPlusLib class:

    GDIPlusLib
    Code:
    Public Shared Function SaveDIBAs(ByVal picname As String, ByVal bminfo As IntPtr, ByVal pixdat As IntPtr) As Boolean
                Dim sd As SaveFileDialog = New SaveFileDialog()
    
                sd.FileName = picname
                sd.Title = "Save bitmap as..."
                sd.Filter = "Bitmap file (*.bmp)|*.bmp|TIFF file (*.tif)|*.tif|JPEG file (*.jpg)|*.jpg|PNG file (*.png)|*.png|GIF file (*.gif)|*.gif|All files (*.*)|*.*"
                sd.FilterIndex = 1
                If sd.ShowDialog() <> DialogResult.OK Then
                    Return False
                End If
    
                Dim clsid As Guid
                If Not GetCodecClsid(sd.FileName, clsid) Then
                    MessageBox.Show("Unknown picture format for extension " + Path.GetExtension(sd.FileName), "Image Codec", MessageBoxButtons.OK, MessageBoxIcon.Information)
                    Return False
                End If
    
                Dim img As IntPtr = IntPtr.Zero
                Dim st As Integer = GdipCreateBitmapFromGdiDib(bminfo, pixdat, img)
                If (st <> 0) Or (Equals(img, IntPtr.Zero)) Then
                    Return False
                End If
    
                st = GdipSaveImageToFile(img, sd.FileName, clsid, IntPtr.Zero)
                GdipDisposeImage(img)
                Return st = 0
            End Function
    
        End Class
    I want to be able to save from the parent form, but if I use:

    Code:
    Private Sub menuItemSaveAs_Click(ByVal sender As Object, ByVal e As System.EventArgs)
                Gdip.SaveDIBAs(Me.Text, bmpptr, pixptr)
            End Sub
    Nothing happens, can anyone help?

    Basically the scanned image appears as an image in the child form.

  2. #2
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,423

    Re: Saving a Scanned Image

    that function calls another 3 functions and a sub that you haven't posted.

    can you post the whole class?

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Nov 2008
    Posts
    233

    Re: Saving a Scanned Image

    Quote Originally Posted by .paul. View Post
    that function calls another 3 functions and a sub that you haven't posted.

    can you post the whole class?
    No problem, see attached, I think this page is limited on the amount of text that can be used.
    Attached Files Attached Files

  4. #4
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,423

    Re: Saving a Scanned Image

    how exactly does the image appear in the child form?
    as an image in a picturebox? or as the forms backgroundimage?

  5. #5
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,423

    Re: Saving a Scanned Image

    if the image does appear as the forms backgroundimage, theres a far simpler way of saving it:

    vb Code:
    1. Private Sub menuItemSaveAs_Click(ByVal sender As Object, ByVal e As System.EventArgs)
    2.     Dim sd As SaveFileDialog = New SaveFileDialog()
    3.  
    4.     sd.FileName = Me.Text
    5.     sd.Title = "Save bitmap as..."
    6.     sd.Filter = "Bitmap file (*.bmp)|*.bmp|TIFF file (*.tif)|*.tif|JPEG file (*.jpg)|*.jpg|PNG file (*.png)|*.png|GIF file (*.gif)|*.gif|All files (*.*)|*.*"
    7.     sd.FilterIndex = 1
    8.     If sd.ShowDialog() <> DialogResult.OK Then
    9.         Dim format As Drawing.Imaging.ImageFormat = Nothing
    10.         Select Case sd.FilterIndex
    11.             Case 0
    12.                 format = Drawing.Imaging.ImageFormat.Bmp
    13.             Case 1
    14.                 format = Drawing.Imaging.ImageFormat.Tiff
    15.             Case 2
    16.                 format = Drawing.Imaging.ImageFormat.Jpeg
    17.             Case 3
    18.                 format = Drawing.Imaging.ImageFormat.Png
    19.             Case 4
    20.                 format = Drawing.Imaging.ImageFormat.Gif
    21.             Case Else
    22.                 Me.BackgroundImage.Save(sd.FileName)
    23.                 Return
    24.         End Select
    25.         Me.BackgroundImage.Save(sd.FileName, format)
    26.     End If
    27.  
    28. End Sub

  6. #6

    Thread Starter
    Addicted Member
    Join Date
    Nov 2008
    Posts
    233

    Re: Saving a Scanned Image

    Quote Originally Posted by .paul. View Post
    if the image does appear as the forms backgroundimage, theres a far simpler way of saving it:

    vb Code:
    1. Private Sub menuItemSaveAs_Click(ByVal sender As Object, ByVal e As System.EventArgs)
    2.     Dim sd As SaveFileDialog = New SaveFileDialog()
    3.  
    4.     sd.FileName = Me.Text
    5.     sd.Title = "Save bitmap as..."
    6.     sd.Filter = "Bitmap file (*.bmp)|*.bmp|TIFF file (*.tif)|*.tif|JPEG file (*.jpg)|*.jpg|PNG file (*.png)|*.png|GIF file (*.gif)|*.gif|All files (*.*)|*.*"
    7.     sd.FilterIndex = 1
    8.     If sd.ShowDialog() <> DialogResult.OK Then
    9.         Dim format As Drawing.Imaging.ImageFormat = Nothing
    10.         Select Case sd.FilterIndex
    11.             Case 0
    12.                 format = Drawing.Imaging.ImageFormat.Bmp
    13.             Case 1
    14.                 format = Drawing.Imaging.ImageFormat.Tiff
    15.             Case 2
    16.                 format = Drawing.Imaging.ImageFormat.Jpeg
    17.             Case 3
    18.                 format = Drawing.Imaging.ImageFormat.Png
    19.             Case 4
    20.                 format = Drawing.Imaging.ImageFormat.Gif
    21.             Case Else
    22.                 Me.BackgroundImage.Save(sd.FileName)
    23.                 Return
    24.         End Select
    25.         Me.BackgroundImage.Save(sd.FileName, format)
    26.     End If
    27.  
    28. End Sub
    My Main form is an MDI Parent Form and the scanned image appears as the whole child form (I assume it is a background image) I want the save button to be on the MDI parent form and have the ability to save the child form that has been scanned, is that what your code is doing?

  7. #7
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,423

    Re: Saving a Scanned Image

    if you put the code in 1 of your mdi parent menus:

    vb Code:
    1. Private Sub menuItemSaveAs_Click(ByVal sender As Object, ByVal e As System.EventArgs)
    2.     Dim sd As New SaveFileDialog()
    3.  
    4.     sd.FileName = Me.ActiveForm.Text
    5.     sd.Title = "Save bitmap as..."
    6.     sd.Filter = "Bitmap file (*.bmp)|*.bmp|TIFF file (*.tif)|*.tif|JPEG file (*.jpg)|*.jpg|PNG file (*.png)|*.png|GIF file (*.gif)|*.gif|All files (*.*)|*.*"
    7.     sd.FilterIndex = 1
    8.     If sd.ShowDialog() = DialogResult.OK Then
    9.         Dim format As Drawing.Imaging.ImageFormat = Nothing
    10.         Select Case sd.FilterIndex
    11.             Case 0
    12.                 format = Drawing.Imaging.ImageFormat.Bmp
    13.             Case 1
    14.                 format = Drawing.Imaging.ImageFormat.Tiff
    15.             Case 2
    16.                 format = Drawing.Imaging.ImageFormat.Jpeg
    17.             Case 3
    18.                 format = Drawing.Imaging.ImageFormat.Png
    19.             Case 4
    20.                 format = Drawing.Imaging.ImageFormat.Gif
    21.             Case Else
    22.                 Me.ActiveForm.BackgroundImage.Save(sd.FileName)
    23.                 Return
    24.         End Select
    25.         Me.ActiveForm.BackgroundImage.Save(sd.FileName, format)
    26.     End If
    27.  
    28. End Sub

  8. #8

    Thread Starter
    Addicted Member
    Join Date
    Nov 2008
    Posts
    233

    Re: Saving a Scanned Image

    Me.ActiveForm.BackgroundImage.Save(sd.FileName, format)

    I get the error:

    Object reference not set to an instance of an object. (on the above line)

  9. #9
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,423

    Re: Saving a Scanned Image

    where did you put the code?
    are you sure the image is in the backgroundimage?

    check the child form. is the image in a picturebox?

  10. #10

    Thread Starter
    Addicted Member
    Join Date
    Nov 2008
    Posts
    233

    Re: Saving a Scanned Image

    The code within the child form:

    Code:
    Imports Telerik.WinControls.UI
    Imports System
    Imports System.Text
    Imports System.Runtime.InteropServices
    Imports System.Drawing
    Imports System.Collections
    Imports System.ComponentModel
    Imports System.Windows.Forms
    Imports DocuStore.GdiPlusLib
    
    Public Class frmScannedDoc
        Inherits System.Windows.Forms.Form
    
        <DllImport("gdi32.dll", ExactSpelling:=True)> Friend Shared Function SetDIBitsToDevice(ByVal hdc As IntPtr, ByVal xdst As Integer, ByVal ydst As Integer, ByVal width As Integer, ByVal height As Integer, ByVal xsrc As Integer, ByVal ysrc As Integer, ByVal start As Integer, ByVal lines As Integer, ByVal bitsptr As IntPtr, ByVal bmiptr As IntPtr, ByVal color As Integer) As Integer
        End Function
        <DllImport("kernel32.dll", ExactSpelling:=True)> Friend Shared Function GlobalLock(ByVal handle As IntPtr) As IntPtr
        End Function
        <DllImport("kernel32.dll", ExactSpelling:=True)> Friend Shared Function GlobalFree(ByVal handle As IntPtr) As IntPtr
        End Function
        <DllImport("kernel32.dll", CharSet:=CharSet.Auto)> Public Shared Sub OutputDebugString(ByVal outstr As String)
        End Sub
    
        Dim bmi As BITMAPINFOHEADER
        Dim bmprect As Rectangle
        Dim dibhand As IntPtr
        Dim bmpptr As IntPtr
        Dim pixptr As IntPtr
    
        Public Sub New(ByVal dibhandp As IntPtr)
            InitializeComponent()
    
            SetStyle(ControlStyles.DoubleBuffer, False)
            SetStyle(ControlStyles.AllPaintingInWmPaint, True)
            SetStyle(ControlStyles.Opaque, True)
            SetStyle(ControlStyles.ResizeRedraw, True)
            SetStyle(ControlStyles.UserPaint, True)
    
            bmprect = New Rectangle(0, 0, 0, 0)
            dibhand = dibhandp
            bmpptr = GlobalLock(dibhand)
            pixptr = GetPixelInfo(bmpptr)
    
            Me.AutoScrollMinSize = New System.Drawing.Size(bmprect.Width, bmprect.Height)
        End Sub
    
        Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
            If disposing Then
                If Not Equals(dibhand, IntPtr.Zero) Then
                    GlobalFree(dibhand)
                    dibhand = IntPtr.Zero
                End If
                If Not (components Is Nothing) Then
                    components.Dispose()
                End If
            End If
            MyBase.Dispose(disposing)
        End Sub
        Private Sub frmScannedDoc_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
        End Sub
    
        Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
            Dim cltrect As Rectangle = ClientRectangle
            Dim clprect As Rectangle = e.ClipRectangle
            Dim scrol As Point = AutoScrollPosition
            Dim realrect As Rectangle = clprect
    
            realrect.X -= scrol.X
            realrect.Y -= scrol.Y
    
            Dim brbg As SolidBrush = New SolidBrush(Color.Black)
            If (realrect.Right > bmprect.Width) Then
                Dim bgri As Rectangle = clprect
                Dim ovri As Integer = bmprect.Width - realrect.X
                If (ovri > 0) Then
                    bgri.X += ovri
                    bgri.Width -= ovri
                End If
                e.Graphics.FillRectangle(brbg, bgri)
            End If
    
            If (realrect.Bottom > bmprect.Height) Then
                Dim bgbo As Rectangle = clprect
                Dim ovbo As Integer = bmprect.Height - realrect.Y
                If (ovbo > 0) Then
                    bgbo.Y += ovbo
                    bgbo.Height -= ovbo
                End If
                e.Graphics.FillRectangle(brbg, bgbo)
            End If
    
            realrect.Intersect(bmprect)
            If Not (realrect.IsEmpty) Then
                Dim bot As Integer = bmprect.Height - realrect.Bottom
                Dim hdc As IntPtr = e.Graphics.GetHdc()
                SetDIBitsToDevice(hdc, clprect.X, clprect.Y, realrect.Width, realrect.Height, realrect.X, bot, 0, bmprect.Height, pixptr, bmpptr, 0)
                e.Graphics.ReleaseHdc(hdc)
                Me.Width = bmi.biWidth
                Me.Height = bmi.biHeight
            End If
        End Sub
    
        Protected Overrides Sub OnPaintBackground(ByVal e As System.Windows.Forms.PaintEventArgs)
        End Sub
    
        Protected Overrides Sub OnClosing(ByVal e As System.ComponentModel.CancelEventArgs)
            MyBase.OnClosing(e)
        End Sub
    
        Private tw As TwainLib.Twain
        Public Function ImgToBitmap(ByVal dibhandp As IntPtr) As Bitmap
            bmprect = New Rectangle(0, 0, 0, 0)
            dibhand = dibhandp
            bmpptr = GlobalLock(dibhand)
            pixptr = GetPixelInfo(bmpptr)
            Dim TempBMP As Bitmap = New Bitmap(bmprect.Width, bmprect.Height)
            Dim TempGrap As Graphics = Graphics.FromImage(TempBMP)
            Dim hdc As IntPtr = TempGrap.GetHdc
            SetDIBitsToDevice(hdc, 0, 0, bmprect.Width, bmprect.Height, 0, 0, 0, bmprect.Height, pixptr, bmpptr, 0)
            TempGrap.ReleaseHdc(hdc)
            TempGrap.Dispose()
            GlobalFree(dibhand)
            dibhand = IntPtr.Zero
            Return (TempBMP)
        End Function
    
        Protected Function GetPixelInfo(ByVal bmpptr As IntPtr) As IntPtr
            bmi = New BITMAPINFOHEADER()
            Marshal.PtrToStructure(bmpptr, bmi)
    
            bmprect.X = Convert.ToInt32(bmprect.Y = 0)
            bmprect.Width = bmi.biWidth
            bmprect.Height = bmi.biHeight
    
            If (bmi.biSizeImage = 0) Then
                bmi.biSizeImage = Convert.ToInt32((Convert.ToDouble((((bmi.biWidth * bmi.biBitCount) + 31) & Hex(Not (31)))) / 2 ^ 3) * bmi.biHeight)
    
            End If
    
            Dim p As Integer = bmi.biClrUsed
            If ((p = 0) And (bmi.biBitCount <= 8)) Then
                p = Convert.ToInt32(Int(1 * 2 ^ bmi.biBitCount))
            End If
            p = (p * 4) + bmi.biSize + CType(bmpptr.ToInt32, Integer)
            Return New IntPtr(p)
    
        End Function
    
    End Class
    
    <StructLayout(LayoutKind.Sequential, Pack:=2)> Public Class BITMAPINFOHEADER
        Public biSize As Integer
        Public biWidth As Integer
        Public biHeight As Integer
        Public biPlanes As Short
        Public biBitCount As Short
        Public biCompression As Integer
        Public biSizeImage As Integer
        Public biXPelsPerMeter As Integer
        Public biYPelsPerMeter As Integer
        Public biClrUsed As Integer
        Public biClrImportant As Integer
    
    
    End Class
    Not sure if it is background image, have added the Scanned Document Code

    I did put your code in the Parent form Save As Button Click

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width