Especificamente: Eu preciso capturar como um bitmap uma região específica do que um picturebox está realmente exibindo. As coordenadas da região são especificadas pelos limites de um controle que eu sobreponho na parte superior da checkbox de figuras (mas que pertence à checkbox de figuras). O controle fica oculto quando eu faço o “instantâneo” da região.
Eu tentei usar methods normais de captura de canvas (CopyFromScreen), mas você não pode realmente controlar o tempo lá. Por isso, estava capturando estados “intersticiais”, como transições entre fotos na minha checkbox de imagens. Freqüentemente, capturava imagens puramente negras (a cor de fundo da checkbox de imagem).
Então eu tentei apenas converter a imagem (propriedade picturebox.image) sendo exibida em um bitmap. O problema é que a checkbox de imagem raramente mostra exatamente a imagem. Ele está exibindo uma parte da imagem, dimensionada e recortada conforme apropriado para o tamanho da imagem (que é zoom). Então, eu não posso simplesmente pegar minhas coordenadas de controle e recortá-las da imagem como um todo.
Então tentei estimar qual parte da imagem estava sendo exibida e corrigi o retângulo com base nisso. Acontece que eu estava basicamente recriando o código “zoom” da checkbox de imagem para fazer isso (usando a proporção da checkbox de imagem, a proporção da imagem, adivinhando em que nível de escala está ocorrendo na imagem se ela é maior ou menor que o picturebox, etc). Não foi bonito.
Então, agora eu preciso de um método de apenas capturar apenas o bitmap atualmente sendo exibido na área do cliente da checkbox de imagem, incluindo a foto e qualquer “letterboxing” preto atualmente sendo exibido em torno dele. Alguém tem um?
Lembre-se que não posso confiar em usar o CopyFromScreen. Não é confiável o suficiente para meus propósitos. Eu acho que preciso de um método de obter o picturebox para me dizer os bits que ele está exibindo.
Isso irá copiar e salvar o conteúdo mostrado atualmente da PictureBox
incluindo um BackgroundImage
(se houver um e se ele brilhar) e também todos os Controls
que pertencem ao PictureBox
, como Labels
etc. Também estão incluídos elementos desenhados no evento Paint
. As coisas desenhadas fora do evento Paint
não são persistentes e não serão incluídas.
using (Bitmap bmp = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height)) { pictureBox1.DrawToBitmap(bmp, pictureBox1.ClientRectangle); bmp.Save(yourfilename, ImageFormat.Png); }
Nota: No meu formulário de teste, a PicureBox
está dentro de um AutoScroll Panel pan_PBscroll
. A PictureBox está exibindo pixels 1: 1 e é, portanto, com uma fotografia carregada, muito maior que o Painel, o Formulário ou até mesmo a Tela. Então, para recortar as partes realmente visíveis, não pude usar o pictureBox1.ClientSize
e o pictureBox1.ClientRectangle
mas usei as dimensões desse Panel. Isso também pode se aplicar a você.
Não tenho certeza sobre seus problemas de tempo. Mas desde que você mencionou CopyFromScreen
aqui estão algumas diferenças:
CopyFromScreen
faz uma cópia de 1: 1 de cada pixel da canvas Control.DrawToBitmap
faz o controle desenhar-se em um bitmap, assim como ele se desenha durante o Paint
Desde que você está usando um PictureBox eu diria para dar uma olhada PictureBox.Image onde você pode obter o object Bitmap .
Espero que ajude.