MyBitmap.vb 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. '一个万能的自动图片类型转换工具类
  2. Imports System.Drawing.Imaging
  3. Public Class MyBitmap
  4. ''' <summary>
  5. ''' 位图缓存。
  6. ''' </summary>
  7. Public Shared BitmapCache As New Dictionary(Of String, MyBitmap)
  8. ''' <summary>
  9. ''' 存储的图片
  10. ''' </summary>
  11. Public Pic As System.Drawing.Bitmap
  12. '自动类型转换
  13. '支持的类:Image,ImageSource,Bitmap,ImageBrush,BitmapSource
  14. Public Shared Widening Operator CType(Image As System.Drawing.Image) As MyBitmap
  15. Return New MyBitmap(Image)
  16. End Operator
  17. Public Shared Widening Operator CType(Image As MyBitmap) As System.Drawing.Image
  18. Return Image.Pic
  19. End Operator
  20. Public Shared Widening Operator CType(Image As ImageSource) As MyBitmap
  21. Return New MyBitmap(Image)
  22. End Operator
  23. Public Shared Widening Operator CType(Image As MyBitmap) As ImageSource
  24. Dim Bitmap = Image.Pic
  25. Dim rect = New System.Drawing.Rectangle(0, 0, Bitmap.Width, Bitmap.Height)
  26. Dim bitmapData = Bitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format32bppArgb)
  27. Try
  28. Dim size = rect.Width * rect.Height * 4
  29. Return BitmapSource.Create(Bitmap.Width, Bitmap.Height, Bitmap.HorizontalResolution, Bitmap.VerticalResolution, PixelFormats.Bgra32, Nothing, bitmapData.Scan0, size, bitmapData.Stride)
  30. Finally
  31. Bitmap.UnlockBits(bitmapData)
  32. End Try
  33. End Operator
  34. Public Shared Widening Operator CType(Image As System.Drawing.Bitmap) As MyBitmap
  35. Return New MyBitmap(Image)
  36. End Operator
  37. Public Shared Widening Operator CType(Image As MyBitmap) As System.Drawing.Bitmap
  38. Return Image.Pic
  39. End Operator
  40. Public Shared Widening Operator CType(Image As ImageBrush) As MyBitmap
  41. Return New MyBitmap(Image)
  42. End Operator
  43. Public Shared Widening Operator CType(Image As MyBitmap) As ImageBrush
  44. Return New ImageBrush(New MyBitmap(Image.Pic))
  45. End Operator
  46. '构造函数
  47. Public Sub New()
  48. End Sub
  49. Public Sub New(FilePathOrResourceName As String)
  50. Try
  51. If FilePathOrResourceName.StartsWith(PathImage) Then
  52. '使用缓存
  53. If BitmapCache.ContainsKey(FilePathOrResourceName) Then
  54. Pic = BitmapCache(FilePathOrResourceName).Pic
  55. Else
  56. Pic = New MyBitmap(CType((New ImageSourceConverter).ConvertFromString(FilePathOrResourceName), ImageSource))
  57. BitmapCache.Add(FilePathOrResourceName, Pic)
  58. End If
  59. Else
  60. '使用这种自己接管 FileStream 的方法加载才能解除文件占用
  61. Using InputStream As New FileStream(FilePathOrResourceName, FileMode.Open)
  62. Pic = New System.Drawing.Bitmap(InputStream)
  63. InputStream.Dispose()
  64. End Using
  65. End If
  66. Catch ex As Exception
  67. Pic = My.Application.TryFindResource(FilePathOrResourceName)
  68. If Pic Is Nothing Then
  69. Pic = New System.Drawing.Bitmap(1, 1)
  70. Log(ex, $"加载位图失败({FilePathOrResourceName})")
  71. Throw
  72. Else
  73. Log(ex, $"指定类型有误的位图加载({FilePathOrResourceName})", LogLevel.Developer)
  74. Exit Try
  75. End If
  76. End Try
  77. End Sub
  78. Public Sub New(Image As ImageSource)
  79. Using MS = New MemoryStream()
  80. Dim Encoder = New PngBitmapEncoder()
  81. Encoder.Frames.Add(BitmapFrame.Create(Image))
  82. Encoder.Save(MS)
  83. Pic = New System.Drawing.Bitmap(MS)
  84. End Using
  85. End Sub
  86. Public Sub New(Image As System.Drawing.Image)
  87. Pic = Image
  88. End Sub
  89. Public Sub New(Image As System.Drawing.Bitmap)
  90. Pic = Image
  91. End Sub
  92. Public Sub New(Image As ImageBrush)
  93. Using MS = New MemoryStream()
  94. Dim Encoder = New BmpBitmapEncoder()
  95. Encoder.Frames.Add(BitmapFrame.Create(Image.ImageSource))
  96. Encoder.Save(MS)
  97. Pic = New System.Drawing.Bitmap(MS)
  98. End Using
  99. End Sub
  100. ''' <summary>
  101. ''' 获取旋转的图片,这个方法不会导致原对象改变且会返回一个新的对象。图片长宽必须相等。
  102. ''' </summary>
  103. ''' <param name="angle">旋转角度(单位为角度)。</param>
  104. Public Function Rotation(angle As Double) As System.Drawing.Bitmap
  105. Dim img As System.Drawing.Image = Me.Pic
  106. Dim bitSize As Single = img.Width
  107. Dim bmp As New System.Drawing.Bitmap(CInt(bitSize), CInt(bitSize), img.PixelFormat)
  108. bmp.SetResolution(img.HorizontalResolution, img.VerticalResolution)
  109. Using g As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bmp)
  110. g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor
  111. g.TranslateTransform(bitSize / 2, bitSize / 2)
  112. g.RotateTransform(angle)
  113. g.TranslateTransform(-bitSize / 2, -bitSize / 2)
  114. g.DrawImage(img, New System.Drawing.Rectangle(0, 0, img.Width, img.Width))
  115. End Using
  116. Return bmp
  117. End Function
  118. ''' <summary>
  119. ''' 获取裁切的图片,这个方法不会导致原对象改变且会返回一个新的对象。
  120. ''' </summary>
  121. Public Function Clip(rect As System.Drawing.Rectangle) As System.Drawing.Bitmap
  122. Dim img As System.Drawing.Image = Pic
  123. Dim bmp As New System.Drawing.Bitmap(rect.Width, rect.Height, img.PixelFormat)
  124. bmp.SetResolution(img.HorizontalResolution, img.VerticalResolution)
  125. Using g As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bmp)
  126. g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor
  127. g.DrawImageUnscaled(img, rect.X, rect.Y)
  128. End Using
  129. Return bmp
  130. End Function
  131. ''' <summary>
  132. ''' 获取左右翻转的图片,这个方法不会导致原对象改变。
  133. ''' </summary>
  134. Public Function LeftRightFilp() As System.Drawing.Bitmap
  135. Dim bmp As New System.Drawing.Bitmap(Pic)
  136. bmp.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipX)
  137. Return bmp
  138. End Function
  139. ''' <summary>
  140. ''' 将图像保存到文件。
  141. ''' </summary>
  142. Public Sub Save(FilePath As String)
  143. Dim encoder As BitmapEncoder = New PngBitmapEncoder()
  144. encoder.Frames.Add(BitmapFrame.Create(Me))
  145. Using fileStream = New System.IO.FileStream(FilePath, FileMode.Create)
  146. encoder.Save(fileStream)
  147. End Using
  148. End Sub
  149. End Class