1 #Region "Microsoft.VisualBasic::d5a73f48c052988031ef69eb27856f11, Microsoft.VisualBasic.Core\Extensions\Image\Bitmap\BitmapBuffer.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Class BitmapBuffer
35     
36     '         Properties: Height, Size, Stride, Width
37     
38     '         Constructor: (+1 OverloadsSub New
39     
40     '         Function: FromBitmap, FromImage, GetEnumerator, GetImage, GetIndex
41     '                   GetPixel, IEnumerable_GetEnumerator, OutOfRange
42     
43     '         Sub: Dispose, SetPixel
44     
45     '         Operators: +
46     
47     
48     ' /********************************************************************************/
49
50 #End Region
51
52 Imports System.Drawing
53 Imports System.Drawing.Imaging
54 Imports System.Runtime.CompilerServices
55 Imports sys = System.Math
56
57 Namespace Imaging.BitmapImage
58
59     ''' <summary>
60     ''' Unsafe memory pointer of the <see cref="Bitmap"/> data buffer.(线程不安全的图片数据对象)
61     ''' </summary>
62     Public Class BitmapBuffer : Inherits Emit.Marshal.Byte
63         Implements IDisposable
64         Implements IEnumerable(Of Color)
65
66         ReadOnly __source As Bitmap
67         ReadOnly __handle As BitmapData
68
69         Protected Sub New(ptr As IntPtr,
70                           byts%,
71                           raw As Bitmap,
72                           handle As BitmapData)
73
74             Call MyBase.New(ptr, byts)
75
76             __source = raw
77             __handle = handle
78
79             Stride = handle.Stride
80             Width = raw.Width
81             Height = raw.Height
82             Size = New Size(Width, Height)
83         End Sub
84
85         Public ReadOnly Property Width As Integer
86         Public ReadOnly Property Height As Integer
87         Public ReadOnly Property Size As Size
88         Public ReadOnly Property Stride As Integer
89
90         ''' <summary>
91         ''' Gets a copy of the original raw image value that which constructed this bitmap object class
92         ''' </summary>
93         ''' <returns></returns>
94         ''' 
95         <MethodImpl(MethodImplOptions.AggressiveInlining)>
96         Public Function GetImage() As Bitmap
97             Return DirectCast(__source.Clone, Bitmap)
98         End Function
99
100         ' pixel:  (1,1)(2,1)(3,1)(4,1)(1,2)(2,2)(3,2)(4,2)
101         ' buffer: BGRA|BGRA|BGRA|BGRA|BGRA|BGRA|BGRA|BGRA|
102         ' bitmap pixels:
103         
104         '    (1,1)(2,1)(3,1)(4,1)
105         '    (1,2)(2,2)(3,2)(4,2)
106         '
107         ' width  = 4 pixel
108         ' height = 2 pixel
109
110         ''' <summary>
111         ''' 返回第一个元素的位置
112         ''' </summary>
113         ''' <param name="x"></param>
114         ''' <param name="y"></param>
115         ''' <returns>B, G, R</returns>
116         ''' <remarks>
117         ''' ###### 2017-11-29 
118         ''' 经过测试,对第一行的数据的计算没有问题
119         ''' </remarks>
120         <MethodImpl(MethodImplOptions.AggressiveInlining)>
121         Public Function GetIndex(x As Integer, y As IntegerAs Integer
122             y = y * (Width * 4)
123             x = x * 4
124             Return x + y
125         End Function
126
127         <MethodImpl(MethodImplOptions.AggressiveInlining)>
128         Public Function OutOfRange(x%, y%) As Boolean
129             Return x < 0 OrElse x >= Width OrElse y < 0 OrElse y >= Height
130         End Function
131
132         ''' <summary>
133         ''' Gets the color of the specified pixel in this <see cref="Bitmap"/>.
134         ''' (<paramref name="x"/>和<paramref name="y"/>都是以零为底的)
135         ''' </summary>
136         ''' <param name="x">The x-coordinate of the pixel to retrieve.</param>
137         ''' <param name="y">The y-coordinate of the pixel to retrieve.</param>
138         ''' <returns>
139         ''' A <see cref="Color"/> structure that represents the color of the specified pixel.
140         ''' </returns>
141         ''' 
142         <MethodImpl(MethodImplOptions.AggressiveInlining)>
143         Public Function GetPixel(x As Integer, y As IntegerAs Color
144             Dim i As Integer = GetIndex(x, y)
145             Dim iA As Byte = buffer(i + 3)
146             Dim iR As Byte = buffer(i + 2)
147             Dim iG As Byte = buffer(i + 1)
148             Dim iB As Byte = buffer(i + 0)
149
150             Return Color.FromArgb(CInt(iA), CInt(iR), CInt(iG), CInt(iB))
151         End Function
152
153         ''' <summary>
154         ''' Sets the color of the specified pixel in this System.Drawing.Bitmap.(这个函数线程不安全)
155         ''' </summary>
156         ''' <param name="x">The x-coordinate of the pixel to set.</param>
157         ''' <param name="y">The y-coordinate of the pixel to set.</param>
158         ''' <param name="color">
159         ''' A System.Drawing.Color structure that represents the color to assign to the specified
160         ''' pixel.</param>
161         ''' 
162         <MethodImpl(MethodImplOptions.AggressiveInlining)>
163         Public Sub SetPixel(x As Integer, y As Integer, color As Color)
164             Dim i As Integer = GetIndex(x, y)
165
166             buffer(i + 3) = color.A
167             buffer(i + 2) = color.R
168             buffer(i + 1) = color.G
169             buffer(i + 0) = color.B
170         End Sub
171
172         ''' <summary>
173         ''' 这个函数会自动复制原始图片数据里面的东西的
174         ''' </summary>
175         ''' <param name="res"></param>
176         ''' <returns></returns>
177         ''' 
178         <MethodImpl(MethodImplOptions.AggressiveInlining)>
179         Public Shared Function FromImage(res As Image) As BitmapBuffer
180             Return BitmapBuffer.FromBitmap(New Bitmap(res))
181         End Function
182
183         Public Shared Function FromBitmap(curBitmap As Bitmap) As BitmapBuffer
184             ' Lock the bitmap's bits.  
185             Dim rect As New Rectangle(0, 0, curBitmap.Width, curBitmap.Height)
186             Dim bmpData As BitmapData = curBitmap.LockBits(
187                 rect,
188                 ImageLockMode.ReadWrite,
189                 curBitmap.PixelFormat)
190
191             Get the address of the first line.
192             Dim ptr As IntPtr = bmpData.Scan0
193             Declare an array to hold the bytes of the bitmap.
194             Dim bytes As Integer = sys.Abs(bmpData.Stride) * curBitmap.Height
195
196             Return New BitmapBuffer(ptr, bytes, curBitmap, bmpData)
197         End Function
198
199         Protected Overrides Sub Dispose(disposing As Boolean)
200             Call Write()
201             Call __source.UnlockBits(__handle)
202         End Sub
203
204         Public Iterator Function GetEnumerator() As IEnumerator(Of Color) Implements IEnumerable(Of Color).GetEnumerator
205             For Each x As Color In buffer.Colors
206                 Yield x
207             Next
208         End Function
209
210         Private Iterator Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
211             Yield GetEnumerator()
212         End Function
213
214         ''' <summary>
215         ''' Current pointer location offset to next position
216         ''' </summary>
217         ''' <param name="bmp"></param>
218         ''' <param name="offset%"></param>
219         ''' <returns></returns>
220         ''' 
221         <MethodImpl(MethodImplOptions.AggressiveInlining)>
222         Public Overloads Shared Operator +(bmp As BitmapBuffer, offset%) As BitmapBuffer
223             bmp.__index += offset
224             Return bmp
225         End Operator
226     End Class
227 End Namespace