none
Salvar imagem de um picturebox RRS feed

  • Pergunta

  • Olá estou com problemas para salvar imagens.

    Estou criando um programa para redimensionar imagens e elas são carregadas em um picturebox e redimensionadas:

    Dim path as String = OpenFileDialog.FileName

    Dim ResizedImage As Image

    Dim NewSize As New Size(MedidaX, MedidaY)

    ResizedImage = New Bitmap(PictureBox1.Image, NewSize)

    PictureBox1.Image = ResizedImage

    para salvar tentei usar:

    PictureBox1.Image.Save(path, Drawing.Imaging.ImageFormat.Jpeg)

    Aparece a mensagem de erro: Erro generico de GDI+

    se tento salvar com a extenção:

    PictureBox1.Image.Save(path & ".jpg", Drawing.Imaging.ImageFormat.Jpeg)

    salvar normal mas aparece a extenção antiga no nome do arquivo.

    Ex: C:\teste.png  fica  C:\teste.png.jpg

    Sei que é possivel usar um Stream para imagens então gostaria de saber qual a melhor alternativa e a solução do problema.

    Agradeço desde ja!

    quinta-feira, 18 de abril de 2013 00:26

Respostas

  • Depois de muito procurar consegui finalmente a solução. Eu precisava cortar o laço entre o arquivo e o programa armazenando a imagem na memoria. Fiz de uma forma bem simples e fácil:

    Dim img As Image
    Dim img_original As Bitmap
    Dim ResizedImage As Image
    Dim imgZoom As Image
    
    Dim openfile As New OpenFileDialog
    
    Private Sub AbrirToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles AbrirToolStripMenuItem.Click
            openfile.Filter = "imagens (*.jpg, *.bmp, *.png, *.gif, *.tiff)|*.jpg; *.bmp; *.png; *.gif; *.tiff"
            If openfile.ShowDialog = Windows.Forms.DialogResult.OK Then
                TextBox3.Text = openfile.FileName
                img = Image.FromFile(openfile.FileName)
                img_original = New Bitmap(img)
                img.Dispose()
                PictureBox1.Image = img_original
                imgZoom = img_original
                Verificar_Dimensões()
            End If
        End Sub

    A imagem é carregada e armazenada na memoria e desconecta-se o arquivo e manipula-se a imagem da memória.

    Para salvar a imagem basta um comando bem simples:

    PictureBox1.Image.Save(TextBox3.Text)

    Mas mesmo assim muito obrigado pelas dicas e pela atenção William.

    Tutorial:

    http://www.devmedia.com.br/vb-net-fechando-o-arquivo-apos-carregar-uma-imagem/6460

    sexta-feira, 19 de abril de 2013 18:23

Todas as Respostas

  • O problema é a imagem carregada no Picturebox trava o arquivo. O erro generico GDI+ na verdade é um "este arquivo esta sendo utilizado por outro processo".

    Como voce mesmo viu, se vc salvar em outro arquivo (no caso vc adicionou um .JPG no nome original) o problema é resolvido.

    Outra forma de resolver isso é usar a soluçao proposta neste artigo:

    http://alperguc.blogspot.ca/2008/11/c-generic-error-occurred-in-gdi.html

    Tenha certeza que no momento em que vc salvar a picturebox nao esteja com a imagem original aberta. Sete a imagem como null.


    William John Adam Trindade
    Analyste-programmeur
    ----------------------------------------------------------

    Sogi informatique ltée

    quinta-feira, 18 de abril de 2013 00:37
    Moderador
  • Ola William a sua dica é em C# e eu converti para VB mas na seguinte linha:

    C#: ImageCodecInfo jpegCodec = GetEncoderInfo(@"image/jpeg");

    VB: Dim jpegCodec As ImageCodecInfo = GetEncoderInfo("image/jpeg")

    A parte sublinhada não está declarada. Poderia me ajudar.

    quinta-feira, 18 de abril de 2013 13:49
  • Creio que tenha sido algo que o autor esqueceu de mencionar no artigo, mas vc pode usar este aqui que funciona:

    Private Shared Function GetEncoderInfo(ByVal mimeType As String) As System.Drawing.Imaging.ImageCodecInfo
            Dim j As Integer
            Try
                Dim encoders() As System.Drawing.Imaging.ImageCodecInfo
                encoders = System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders()
     
                j = 0
                While j > encoders.Length
                    If encoders(j).MimeType = mimeType Then
                        Return encoders(j)
                    End If
                    j += 1
                End While
            Catch ex As Exception
                Debug.Assert(False, "Error GetEncoderInfo: " & ex.Message)
                Throw New Exception("Error GetEncoderInfo", ex)
            End Try
            Return Nothing
     
        End Function

    fonte:http://icodesnip.com/snippet/vbnet/getencoderinfo-code-snippets

    Att


    William John Adam Trindade
    Analyste-programmeur
    ----------------------------------------------------------

    Sogi informatique ltée


    quinta-feira, 18 de abril de 2013 14:07
    Moderador
  • William eu não estou conseguindo salvar porque a imagem está sendo utilizada em outro processo. Comando para abrir a imagem:

    Dim openfile As New OpenFileDialog
        Private Sub AbrirToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles AbrirToolStripMenuItem.Click
            openfile.Filter = "imagens (*.jpg, *.bmp, *.png, *.gif, *.tiff)|*.jpg; *.bmp; *.png; *.gif; *.tiff"
            If openfile.ShowDialog = Windows.Forms.DialogResult.OK Then
                PictureBox1.Image = Image.FromFile(openfile.FileName)
                img_original = PictureBox1.Image
                TextBox1.Text = img_original.PhysicalDimension.Width
                TextBox2.Text = img_original.PhysicalDimension.Height
                NumericUpDown2.Value = img_original.PhysicalDimension.Width
                NumericUpDown3.Value = img_original.PhysicalDimension.Height
                NumericUpDown4.Value = img_original.PhysicalDimension.Width
                NumericUpDown5.Value = img_original.PhysicalDimension.Height
                Umporcento1 = Val(NumericUpDown2.Value) / Val(100)
                Umporcento2 = Val(NumericUpDown3.Value) / Val(100)
                TextBox3.Text = openfile.FileName
                nome = System.IO.Path.GetFileNameWithoutExtension(path)
                extenção = System.IO.Path.GetExtension(path)
                imgZoom = New Bitmap(img_original)
            End If
        End Sub

    O problema é na função SaveJpeg:

    Friend Shared Sub SaveJpeg(ByVal path As String, ByVal img As Image, ByVal quality As Integer)
            Dim qualityParam As EncoderParameter = New EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality)
            Dim jpegCodec As ImageCodecInfo = GetEncoderInfo("image/jpeg")
            Dim EncoderParams As EncoderParameters = New EncoderParameters(1)
            EncoderParams.Param(0) = qualityParam
            Dim mss As New System.IO.MemoryStream()
            Dim fs As System.IO.FileStream = New System.IO.FileStream(path, System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite)
            img.Save(mss, jpegCodec, EncoderParams)
            Dim matriz As Byte() = mss.ToArray()
            fs.Write(matriz, 0, matriz.Length)
            mss.Close()
            fs.Close()
        End Sub

    O evento para salvar a imagem:

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
            PictureBox1.Image = Nothing
            PictureBox1.Dispose()
            openfile.Dispose()
            SaveJpeg(TextBox3.Text, ResizedImage, QualityMode.High)
        End Sub


    quinta-feira, 18 de abril de 2013 17:13
  • Ok.. mas onde esta definida a ResizedImage?

    Ela esta em uma picturebox?

    Att


    William John Adam Trindade
    Analyste-programmeur
    ----------------------------------------------------------

    Sogi informatique ltée

    quinta-feira, 18 de abril de 2013 17:44
    Moderador
  • está no evento do botão para redimensionar a imagem:

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Select Case CheckBox1.CheckState
                Case CheckState.Checked
                    Dim valX As Double = Val(img_original.Size.Width) / 100
                    valX = Val(valX) * Val(TrackBar2.Value)
                    valX = Val(valX) \ Val(1)
                    Label15.Text = valX
                    Dim valY As Double = Val(img_original.Size.Height) / 100
                    valY = Val(valY) * Val(TrackBar2.Value)
                    valY = Val(valY) \ Val(1)
                    Label16.Text = valY
                    Dim NewSize As New Size(Label15.Text, Label16.Text)
                    ResizedImage = New Bitmap(img_original, NewSize)
                    PictureBox1.Image = ResizedImage
                Case CheckState.Unchecked
                    Dim NewSize As New Size(TrackBar1.Value, TrackBar2.Value)
                    ResizedImage = New Bitmap(img_original, NewSize)
                    PictureBox1.Image = ResizedImage
            End Select
            altera = True
        End Sub

    quinta-feira, 18 de abril de 2013 21:02
  • Depois de muito procurar consegui finalmente a solução. Eu precisava cortar o laço entre o arquivo e o programa armazenando a imagem na memoria. Fiz de uma forma bem simples e fácil:

    Dim img As Image
    Dim img_original As Bitmap
    Dim ResizedImage As Image
    Dim imgZoom As Image
    
    Dim openfile As New OpenFileDialog
    
    Private Sub AbrirToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles AbrirToolStripMenuItem.Click
            openfile.Filter = "imagens (*.jpg, *.bmp, *.png, *.gif, *.tiff)|*.jpg; *.bmp; *.png; *.gif; *.tiff"
            If openfile.ShowDialog = Windows.Forms.DialogResult.OK Then
                TextBox3.Text = openfile.FileName
                img = Image.FromFile(openfile.FileName)
                img_original = New Bitmap(img)
                img.Dispose()
                PictureBox1.Image = img_original
                imgZoom = img_original
                Verificar_Dimensões()
            End If
        End Sub

    A imagem é carregada e armazenada na memoria e desconecta-se o arquivo e manipula-se a imagem da memória.

    Para salvar a imagem basta um comando bem simples:

    PictureBox1.Image.Save(TextBox3.Text)

    Mas mesmo assim muito obrigado pelas dicas e pela atenção William.

    Tutorial:

    http://www.devmedia.com.br/vb-net-fechando-o-arquivo-apos-carregar-uma-imagem/6460

    sexta-feira, 19 de abril de 2013 18:23