MyBitmap.vb 6.3 KB

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