1 |
#Region "Microsoft.VisualBasic::3ff6c2d9a4a17f52213c689275ecc5b7, Microsoft.VisualBasic.Core\Extensions\Image\Bitmap\BitmapScale.vb"
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
#End Region
|
52 |
|
53 |
Imports System.Drawing
|
54 |
Imports System.Drawing.Imaging
|
55 |
Imports System.Math
|
56 |
Imports System.Runtime.CompilerServices
|
57 |
Imports Microsoft.VisualBasic.Emit
|
58 |
Imports sys = System.Math
|
59 |
|
60 |
Namespace Imaging.BitmapImage
|
61 |
|
62 |
|
63 |
|
64 |
|
65 |
Public Module BitmapScale
|
66 |
|
67 |
<Extension>
|
68 |
Public Function GetBinaryBitmap(res As Image, Optional style As BinarizationStyles = BinarizationStyles.Binary) As Bitmap
|
69 |
Dim bmp As New Bitmap(DirectCast(res.Clone, Image))
|
70 |
bmp.Binarization(style)
|
71 |
Return bmp
|
72 |
End Function
|
73 |
|
74 |
Public Enum BinarizationStyles
|
75 |
SparseGray = 3
|
76 |
Binary = 4
|
77 |
End Enum
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
<param name="byts">Unmanaged memory pointer that point to the bitmap data buffer.</param>
|
83 |
Public Delegate Sub PixelScanPointer(byts As Marshal.Byte)
|
84 |
|
85 |
|
86 |
A generic bitmap pixel scan framework that using memory pointer
|
87 |
|
88 |
<param name="curBitmap"></param>
|
89 |
<param name="scan"></param>
|
90 |
<Extension>
|
91 |
Public Sub BitmapPixelScans(ByRef curBitmap As Bitmap, scan As PixelScanPointer)
|
92 |
|
93 |
Dim rect As New Rectangle(0, 0, curBitmap.Width, curBitmap.Height)
|
94 |
Dim bmpData As BitmapData = curBitmap.LockBits(
|
95 |
rect,
|
96 |
ImageLockMode.ReadWrite,
|
97 |
curBitmap.PixelFormat
|
98 |
)
|
99 |
|
100 |
Dim ptr As IntPtr = bmpData.Scan0
|
101 |
|
102 |
Dim bytes As Integer = sys.Abs(bmpData.Stride) * curBitmap.Height
|
103 |
|
104 |
Using rgbValues As Marshal.Byte = New Marshal.Byte(ptr, bytes)
|
105 |
|
106 |
|
107 |
Call scan(rgbValues)
|
108 |
End Using
|
109 |
|
110 |
|
111 |
Call curBitmap.UnlockBits(bmpData)
|
112 |
End Sub
|
113 |
|
114 |
|
115 |
|
116 |
|
117 |
<param name="curBitmap"></param>
|
118 |
<remarks>
|
119 |
http://www.codeproject.com/Articles/1094534/Image-Binarization-Using-Program-Languages
|
120 |
|
121 |
The .net Bitmap object keeps a reference to HBITMAP handle, Not to the underlying bitmap itself.
|
122 |
So, single pixel access call to <see cref="Bitmap.SetPixel"/>/<see cref="Bitmap.GetPixel"/> Or
|
123 |
even retrieve Width/Height properties does something Like:
|
124 |
lock handle In place-Get/Set value/unlock handle. It Is the most inefficient way To manipulate bitmaps In .NET.
|
125 |
The author should read about <see cref="Bitmap.LockBits"/> first.
|
126 |
</remarks>
|
127 |
<Extension> Public Sub Binarization(ByRef curBitmap As Bitmap, Optional style As BinarizationStyles = BinarizationStyles.Binary)
|
128 |
Dim iR As Integer = 0
|
129 |
Dim iG As Integer = 0
|
130 |
Dim iB As Integer = 0
|
131 |
Dim scanInternal As PixelScanPointer =
|
132 |
_
|
133 |
Sub(byts As Marshal.Byte)
|
134 |
|
135 |
|
136 |
Do While Not byts.NullEnd(3)
|
137 |
|
138 |
iR = byts(2)
|
139 |
|
140 |
iG = byts(1)
|
141 |
|
142 |
iB = byts(0)
|
143 |
|
144 |
|
145 |
If (iR + iG + iB) / 3 > 100 Then
|
146 |
|
147 |
byts(2) = 255
|
148 |
byts(1) = 255
|
149 |
byts(0) = 255
|
150 |
Else
|
151 |
|
152 |
byts(2) = 0
|
153 |
byts(1) = 0
|
154 |
byts(0) = 0
|
155 |
End If
|
156 |
|
157 |
|
158 |
byts += style
|
159 |
Loop
|
160 |
End Sub
|
161 |
|
162 |
Call curBitmap.BitmapPixelScans(scanInternal)
|
163 |
End Sub
|
164 |
|
165 |
|
166 |
调整图像的对比度
|
167 |
|
168 |
<param name="bmp"></param>
|
169 |
<param name="contrast#"></param>
|
170 |
<Extension> Public Sub AdjustContrast(ByRef bmp As Bitmap, contrast#)
|
171 |
Dim contrastLookup As Byte() = New Byte(255) {}
|
172 |
Dim newValue As Double = 0
|
173 |
Dim c As Double = (100.0 + contrast) / 100.0
|
174 |
|
175 |
c *= c
|
176 |
|
177 |
For i As Integer = 0 To 255
|
178 |
newValue = CDbl(i)
|
179 |
newValue /= 255.0
|
180 |
newValue -= 0.5
|
181 |
newValue *= c
|
182 |
newValue += 0.5
|
183 |
newValue *= 255
|
184 |
|
185 |
If newValue < 0 Then
|
186 |
newValue = 0
|
187 |
End If
|
188 |
If newValue > 255 Then
|
189 |
newValue = 255
|
190 |
End If
|
191 |
|
192 |
contrastLookup(i) = CByte(Truncate(newValue))
|
193 |
Next
|
194 |
|
195 |
Using bitmapdata As BitmapBuffer = BitmapBuffer.FromBitmap(bmp)
|
196 |
Dim destPixels As BitmapBuffer = bitmapdata
|
197 |
|
198 |
For y As Integer = 0 To bitmapdata.Height - 1
|
199 |
destPixels += bitmapdata.Stride
|
200 |
|
201 |
For x As Integer = 0 To bitmapdata.Width - 1
|
202 |
destPixels(x * PixelSize) = contrastLookup(destPixels(x * PixelSize))
|
203 |
destPixels(x * PixelSize + 1) = contrastLookup(destPixels(x * PixelSize + 1))
|
204 |
destPixels(x * PixelSize + 2) = contrastLookup(destPixels(x * PixelSize + 2))
|
205 |
Next
|
206 |
Next
|
207 |
End Using
|
208 |
End Sub
|
209 |
|
210 |
|
211 |
convert color bitmaps to grayscale.(灰度图)
|
212 |
|
213 |
<param name="source"></param>
|
214 |
<returns></returns>
|
215 |
<Extension> Public Function Grayscale(source As Image) As Bitmap
|
216 |
Dim curBitmap As New Bitmap(source)
|
217 |
Dim iR As Integer = 0
|
218 |
Dim iG As Integer = 0
|
219 |
Dim iB As Integer = 0
|
220 |
Dim scanInternal As PixelScanPointer =
|
221 |
_
|
222 |
Sub(byts As Marshal.Byte)
|
223 |
|
224 |
Do While Not byts.NullEnd(3)
|
225 |
|
226 |
iR = byts(2)
|
227 |
|
228 |
iG = byts(1)
|
229 |
|
230 |
iB = byts(0)
|
231 |
|
232 |
Dim luma% = GrayScale(iR, iG, iB)
|
233 |
|
234 |
byts(2) = luma
|
235 |
byts(1) = luma
|
236 |
byts(0) = luma
|
237 |
|
238 |
byts += BinarizationStyles.Binary
|
239 |
Loop
|
240 |
End Sub
|
241 |
|
242 |
Call curBitmap.BitmapPixelScans(scanInternal)
|
243 |
Return curBitmap
|
244 |
End Function
|
245 |
|
246 |
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
247 |
Public Function GrayScale(R%, G%, B%) As Integer
|
248 |
Return CInt(Truncate(R * 0.3 + G * 0.59 + B * 0.11))
|
249 |
End Function
|
250 |
|
251 |
|
252 |
Color gray scale
|
253 |
|
254 |
<param name="c"></param>
|
255 |
<returns></returns>
|
256 |
|
257 |
<MethodImpl(MethodImplOptions.AggressiveInlining)>
|
258 |
<Extension>
|
259 |
Public Function GrayScale(c As Color) As Integer
|
260 |
Return GrayScale(c.R, c.G, c.B)
|
261 |
End Function
|
262 |
|
263 |
|
264 |
How many bytes does this bitmap contains?
|
265 |
|
266 |
<param name="rect">The bitmap size or a specific region on the bitmap.</param>
|
267 |
<returns></returns>
|
268 |
<Extension>
|
269 |
Public Function ByteLength(rect As Rectangle) As Integer
|
270 |
Dim width As Integer = rect.Width * PixelSize
|
271 |
Return width * rect.Height
|
272 |
End Function
|
273 |
|
274 |
|
275 |
Convert the bitmap memory bytes into pixels
|
276 |
|
277 |
<param name="buffer"></param>
|
278 |
<returns></returns>
|
279 |
<Extension>
|
280 |
Public Iterator Function Colors(buffer As Byte()) As IEnumerable(Of Color)
|
281 |
Dim iR As Byte
|
282 |
Dim iG As Byte
|
283 |
Dim iB As Byte
|
284 |
|
285 |
|
286 |
For i As Integer = 0 To buffer.Length - 1 Step PixelSize
|
287 |
iR = buffer(i + 2)
|
288 |
iG = buffer(i + 1)
|
289 |
iB = buffer(i + 0)
|
290 |
|
291 |
Yield Color.FromArgb(CInt(iR), CInt(iG), CInt(iB))
|
292 |
Next
|
293 |
End Function
|
294 |
End Module
|
295 |
End Namespace
|