VB.NET Modify a Bitmap in a function Call - vb.net

I'm trying to modify a bitmap in a function call.
Without the function call I can do
'MyBitMap - an existing bitmap of what I want to modify
Using NewBitMap as BitMap = MyBitMap.Clone 'make copy
Dim G as Graphics = Graphics.FromImage(MyBitMap) 'Draw graphics to MyBitMap
G.Clear(color.white) 'Clear image
G.DrawImage(NewBitMap, -10, 0) 'Shift Image to left 10
PictureBox1.Image = MyBitMap
End Using
works fine no memmory overflow or anything
In a sub it works fine
Sub BMScroll_S(BM as BitMap, dx as integer, dy as integer)
using BMtemp as BitMap = BM.Clone
Dim G as Graphics = Graphics.FromImage(BM)
G.Clear(color.white)
G.DrawImage(BMTemp, dx, dy)
End Using
End Sub
Call BMScroll_S(MyBitMap, -10, 0)
PictureBox1.Image = MyBitMap
works fine, but if I try to create a Function to return a Bitmap
Function BMScroll_F(BM as BitMap, dx as integer, dy as integer) as Bitmap
BMScroll_F = New Bitmap(BM)
Using BMtemp As Bitmap = BM.Clone
Dim G As Graphics = Graphics.FromImage(BMScroll_F)
G.Clear(Color.White)
G.DrawImage(BMtemp, dx, dy)
BM.Dispose()
End Using
End Function
MyBitMap=BMScroll_F(MyBitMap, -10, 0)
PictureBox1.Image = MyBitMap
here I have a Memory Leak and after more and more iterations, it will crash.
I suppose in the function call you are returning a bitmap as well as the fact that BitMaps are passed ByRef so they will continue to exist. I thought BM.Dispose might get rid of it - but it doesn't. I not quite sure how to solve my memory leak (if it is in fact due to my supposition). Granted, I could continue on with the Subroutine but I'd like to know how to solve this problem any way. Any help would be appreciated.

Related

Create a new picture along the GraphicsPath

Is there some way to copy a GraphicsPath and the enclosed figure into a new picture?
I have the rectangle, the points of the GraphicsPath available. The path is definitely in the rectangle.
I already googled but the result is poor. So far, I can only copy a certain area (rectangle) into a new picture, see source code.
Using Extracted As Bitmap = New Bitmap(rect.Width, rect.Height, Imaging.PixelFormat.Format32bppArgb)
Using Grp As Graphics = Graphics.FromImage(Extracted)
Grp.DrawImage(Picture1, 0, 0, rect, GraphicsUnit.Pixel)
End Using
If System.IO.Directory.Exists("C:\Users\xy\Desktop") Then
Extracted.Save("C:\Users\xy\Desktop\1.png", Imaging.ImageFormat.Png)
End If
End Using
I have found something here:
This is the solution translated into VB.Net and with Option Strict On and Option Infer Off.
Using bmpSource As Bitmap = New Bitmap(Form1.Pfad_Bild)
Dim rectCutout As RectangleF = gp.GetBounds()
Using m As Matrix = New Matrix()
m.Translate(-rectCutout.Left, -rectCutout.Top)
gp.Transform(m)
End Using
Using bmpCutout As Bitmap = New Bitmap(CInt(rectCutout.Width), CInt(rectCutout.Height))
Using graphicsCutout As Graphics = Graphics.FromImage(bmpCutout)
graphicsCutout.Clip = New Region(gp)
graphicsCutout.DrawImage(bmpSource, CInt(-rectCutout.Left), CInt(-rectCutout.Top))
If System.IO.Directory.Exists("C:\Users\xy\Desktop") Then
bmpCutout.Save("C:\Users\xy\Desktop\1.png", Imaging.ImageFormat.Png)
End If
End Using
End Using
End Using

Issue with Lockbits in DrawImage

Looking for some much appreciated help. I'm trying to draw a smaller bitmap into a larger bitmap. I'm trying to use Lockbits to make the process go faster. But my .DrawImage function will not execute. The error is a general GDI+ error (Unhandled Exception). This is my code snippet. What am i doing wrong? The Misc.Lockbitmap is verified to work so i don't think the error is there, but I can put that code up here as well if that helps.
I should add that this is part of a much bigger code. To clarify: I am able to use execute the line with .DrawImage if i disable the lockbits.
Dim largerFile As New Bitmap(BitMapSizeX, BitMapSizeY)
Call MiscClass.LockBitmap(largerFile, PixBytes, RowSizeBytes)
Dim GraphicsModifier As Graphics = Graphics.FromImage(largerFile)
Dim currentPic As New Bitmap(smallerFilePath.Tostring) ' & ".jpg")
GraphicsModifier.DrawImage(currentPic, picAndLoc.XLoc, picAndLoc.YLoc, ComponentSize, ComponentSize)
Public Shared m_BitmapData As BitmapData
' Lock the bitmap's data.
Public Shared Sub LockBitmap(ByRef bm As Bitmap, ByRef PixBytes() As Byte, ByRef RowSizeBytes As Integer)
Dim bounds As Rectangle = New Rectangle(0, 0, bm.Width, bm.Height)
m_BitmapData = bm.LockBits(bounds, Imaging.ImageLockMode.ReadWrite, Imaging.PixelFormat.Format24bppRgb)
RowSizeBytes = m_BitmapData.Stride
' Allocate room for the data.
Dim total_size As Integer = m_BitmapData.Stride * m_BitmapData.Height
ReDim PixBytes(total_size)
Marshal.Copy(m_BitmapData.Scan0, PixBytes, 0, total_size)
End Sub

Capture Snapshot image from video in AxWindowsMediaPlayer in vb.net

I am looking for a function to take a screenshot from an embedded Windows Media Player control in a VB.NET Windows form. I am currently using the following function; it works fine, but the problem is that x and y are different on each screen so it would be better if I could use a function in the AxWindowsMediaPlayer control itself, like .Capture() or a similar method.
Private Function TakeImage(ByVal X As Integer, ByVal Y As Integer, ByVal Width As Integer, ByVal Height As Integer) As Bitmap
Dim Img As New Bitmap(Width, Height)
Dim g As Graphics = Graphics.FromImage(Img)
g.CopyFromScreen(X, Y, 0, 0, Img.Size)
g.Dispose()
Return Img
End Function
Dim bmp As Bitmap = TakeImage(x, y - 20, AxWindowsMediaPlayer1.Width, AxWindowsMediaPlayer1.Height)
bmp.Save("E:\pics\" & i.ToString & ".jpg", Drawing.Imaging.ImageFormat.Jpeg)
You could try Ctl.PointToScreen() to get an absolute screen point for CopyFromScreen.
I would get the AxWMP.PointToScreen in the procedure each time since the form could move. Pass them to CopyFromScreen and see if that works. I am not sure if it expects X,Y relative to the app, form or what but Screen, does mean screen.

How to load a BitmapImage in MetroUI Dynamically

I've been experimenting with Windows 8 and Metro UI, I've written a perfectly reasonable load of a bitmap image, but it doesn't seem to be loading, any help is appreciated.
Public Sub New(Image As String)
Debug.Print("ms-resource://MyAssembly/" & Image)
Img = New ImageBrush()
Dim Bitmap As New BitmapImage()
Bitmap.UriSource = New Uri("ms-resource://MyAssembly/" & Image, UriKind.Absolute)
Img.ImageSource = Bitmap
Width = Bitmap.PixelWidth
Height = Bitmap.PixelHeight
Debug.Print("Height: " & Height & " Width: " & Width)
End Sub
In this example Width and Height always take values of zero.
It is rendered in the same class..
Public Sub Render(X As Integer, Y As Integer, Canv As Canvas)
Dim Sprite As New Shapes.Rectangle
Sprite.Width = CDbl(Width)
Sprite.Height = CDbl(Height)
Sprite.Fill = Img
Sprite.SetValue(Canvas.TopProperty, CDbl(Y))
Sprite.SetValue(Canvas.LeftProperty, CDbl(X))
Canv.Children.Add(Sprite)
End Sub
End Class
And here is where it is created/called:
V = New Sprite("Images/Test.bmp")
gameRoot.Children.Clear()
V.Render(100, 100, gameRoot)
===
it isn't a problem with my canvas object, because if i fill it with Sprite.Fill = New SolidColorBrush(Colors.White) then it works fine, and I see a white square on my screen, the bitmap in question is set to "Copy Always", and is in the destination folder when i view it.
I'm not quite sure what I'm doing wrong.
Well I managed to figure this out myself.
You can get a base uri by using
Me.Uri; or in C# This.Uri.
Here is the finished code that will enable anyone to load a bitmap image into a canvas; and even rotate it.
I wrote this myself, so anyone who discovers it having the same problem can feel free to use it as they please.
Image must take the format "FilePath/Image.extension"
Public Class Sprite
'Public Shared Baseuri As Uri
Public Img As ImageBrush
Public Bitmap As BitmapImage
Public Sub New(Image As String, Base As Uri)
'Debug.Print("BASE:" & Base.ToString)
'Debug.Print("USING:" & Image)
'Debug.Print("RESULT:" & New Uri(Base, Image).ToString)
Img = New ImageBrush()
Bitmap = New BitmapImage(New Uri(Base, Image))
End Sub
Public Overloads Sub Render(X As Integer, Y As Integer, Width As Integer, Height As Integer, Canv As Canvas)
Img.ImageSource = Bitmap
Dim Sprite As New Shapes.Rectangle
Sprite.Width = CDbl(Width)
Sprite.Height = CDbl(Height)
Sprite.Fill = Img
Sprite.SetValue(Canvas.TopProperty, CDbl(Y))
Sprite.SetValue(Canvas.LeftProperty, CDbl(X))
Canv.Children.Add(Sprite)
End Sub
Public Overloads Sub Render(X As Integer, Y As Integer, Width As Integer, Height As Integer, Canv As Canvas, Angle As Integer)
Img.ImageSource = Bitmap
Dim Sprite As New Shapes.Rectangle
Sprite.Width = CDbl(Width)
Sprite.Height = CDbl(Height)
Sprite.Fill = Img
Sprite.SetValue(Canvas.TopProperty, CDbl(Y))
Sprite.SetValue(Canvas.LeftProperty, CDbl(X))
Dim v As New Windows.UI.Xaml.Media.RotateTransform
v.Angle = CDbl(Angle)
v.CenterX = Width / 2
v.CenterY = Height / 2
Sprite.RenderTransform = v
Canv.Children.Add(Sprite)
End Sub
End Class

Invert or Flip Text in RDLC report

Okay, I've learned a bit more and have rephrased my question. I've got a need to flip or invert text 180 degrees (so it appears upside-down) on a RDLC report. I have some custom VB code that takes the text, converts it to a bitmap, then flips the rotates the canvas 180 degrees. The effect of this makes the text look a bit.. dithered... or fuzzy. It's not a sharp font anymore. The problem I'm experiencing is I'm using a special TTF Barcode font that creates something a scanner can read. When I flip the barcode font, the fuzziness isn't good since the barcode lines are so close together and the scanner cannot read it. Here's the code:
Function LoadImage(ByVal sImageText as String, iRotationAngle as Integer, ByVal sFontName as String, iFontSize as Integer)
Dim bmpImage As New Drawing.Bitmap(1, 1)
Dim iWidth As Integer = 0
Dim iHeight As Integer = 0
'// Create the Font object for the image text drawing.
Dim MyFont As New Drawing.Font(sFontName, iFontSize) ', System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point)
'// Create a graphics object to measure the text's width and height.
Dim MyGraphics As Drawing.Graphics = Drawing.Graphics.FromImage(bmpImage)
'// This is where the bitmap size is determined.
iWidth = MyGraphics.MeasureString(sImageText, MyFont).Width
iHeight = MyGraphics.MeasureString(sImageText, MyFont).Height
'// Create the bmpImage again with the correct size for the text and font.
bmpImage = New Drawing.Bitmap(bmpImage, New Drawing.Size(iWidth, iHeight))
'// Add the colors to the new bitmap.
MyGraphics = Drawing.Graphics.FromImage(bmpImage)
MyGraphics.Clear(Drawing.Color.White)
MyGraphics.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
MyGraphics.TranslateTransform(iWidth,iHeight)
MyGraphics.RotateTransform(iRotationAngle)
MyGraphics.DrawString(sImageText, MyFont, New Drawing.SolidBrush(Drawing.Color.Black), 0, 0)
MyGraphics.Flush()
Dim stream As IO.MemoryStream = New IO.MemoryStream
Dim bitmapBytes As Byte()
'Create bitmap
bmpImage.Save(stream, System.Drawing.Imaging.ImageFormat.Bmp)
bitmapBytes = stream.ToArray
stream.Close()
bmpImage.Dispose()
Return bitmapBytes
End Function
I really don't know why there's not a built-in way to just flip text. It'll let me reverse it left-to-right. Ridiculous.
Thanks