|
Ein Programm in der Programmiersprache | A program in the programming language | |||
Visual BASIC 2015 | ||||
Code für eine Bildverkleinerung durch Pixel-Rechnung | Code for an Image-Downsize by Pixel-Calculus | |||
Ein Bild wird verkleinert durch Pixelrechnung mit unganzzahligen Pixels. Es sind 2 Methoden
zur Auswahl, 1. GetSetPixelBitmap und 2. LockUnlockBitmap. GetSetPixel ist etwas langsamer im Zugriff auf das
Bitmap-Objekt. Die LockUnlockBitmap-Prozedur ist in einer eigenen Klasse, weil es kompliziertere Funktionen
enthält. Die Prozedure kopiert die Bildinformation in ein Array und wieder zurück. Dazwischen kann sie im Array
nach Belieben verarbeitet werden und sie stört nicht in der Main, wo viele andere Funktionen vorkommen können.
| A picture is sized down by pixel-calculus with uninteger pixels. There are 2 methods
selectable, 1. GetSetPixelBitmap und 2. LockUnlockBitmap. GetSetPixel is slower in access to the bitmap-object.
The LockUnlockBitmap-procedure is in a separated class, because it contains more complicated functions.
The procedure copies the image-information into an array and back again. In between it can be processed in the
array at pleasure and does not disturb in the Main, where many other functions can occor.
| |||
Nähere Erläuterung des Prinzips der Pixelrechnung auf der Seite Gemacht mit der Unterstützung der ActiveVB-Community Das Programm ist getestet vor der Publikation, aber es kann keine Garantie gegeben werden, dass es fehlerfrei ist | Closer explaination of the principle of the pixel-calculus on page Made with the support of the ActiveVB-Community The program ist tested before publication, but there can be given no guarantee, that it is free of errors | |||
2. Juli 2016 | July 2nd 2016 |
Image DownsizeDisplay in the PictureBoxProgram-Code' Program in Visual BASIC 2015' ============================================================================================== Option Strict On Option Explicit On Public Class Form1 Private PGM As New Program Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click PGM.Main() PGM.DisplayResult() End Sub Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged If Not IsNumeric(TextBox1.Text) Then DownSizeFactor = 0 : Exit Sub DownSizeFactor = CSng(Val(TextBox1.Text)) If DownSizeFactor >= 100 Then DownSizeFactor = 0 End Sub End Class ' ============================================================================================== Option Strict On Option Explicit On Module GlobalSpecs Public Const fSpec_Img1 As String = "D:\YourPath\doll-big.jpg" ' for loading Public Const method As String = "LockUnlockBitmap" ' GetSetPixel, LockUnlockBitmap Public DownSizeFactor As Single = 0 ' in % Public PiBxW As Integer = Form1.PictureBox1.Width Public PiBxH As Integer = Form1.PictureBox1.Height Public xCenter As Integer = PiBxW \ 2 Public Img1, Img2 As Image Public ImgArray(PiBxW - 1, PiBxH - 1, 2) As Integer Public Img1Array(PiBxW - 1, PiBxH - 1, 2) As Integer Public Img2Array(PiBxW - 1, PiBxH - 1, 2) As Integer Public Img1Width As Integer = PiBxW, Img1Height As Integer = PiBxH Public Img2Width As Integer = PiBxW, Img2Height As Integer = PiBxH Public BrkErrMsg As New List(Of String) Public aTmp(,,) As Integer = Nothing Public Sub CopyArrayToTmp(ToFrom As String, aNr As Byte) Dim ToTmp As Boolean = ToFrom = "To" Select Case aNr Case 1 : If ToTmp Then aTmp = Img1Array Else Img1Array = aTmp Case 2 : If ToTmp Then aTmp = Img2Array Else Img2Array = aTmp End Select End Sub End Module ' ============================================================================================== Option Strict On Option Explicit On Public Class Program Private LOCK As New BitMapBitLock Public Sub Main() ' Jumping out of the sub means BrkErr with automatic display With Form1.PictureBox1 If Not LoadImgFromDisk(fSpec_Img1) Then Exit Sub ' as bitmap in img1 .Image = Img1 ' PictureBox.Image is a property of PictureBox If DownSizeFactor = 0 Then MsgBox("Input Downsize-Faktor") : Exit Sub MsgBox("start downsize") If method = "GetSetPixel" Then CopyImgToArray(1, 1) ' Img1 to Img1Array If method = "LockUnlockBitmap" Then LOCK.CopyImgToArray(1, 1) DownsizeImage(DownSizeFactor) ' Result in Img2Array If method = "GetSetPixel" Then CopyArrayToImg(2, 1) ' Img2Array to Img1 If method = "LockUnlockBitmap" Then LOCK.CopyArrayToImg(2, 1) .Image = Img1 ' Display result in PictureBox End With End Sub Public Sub DisplayResult() ' as text in the picturebox If BrkErrMsg.Count < 1 Then Exit Sub BrkErrMsg.Insert(0, "BrkErrMsg") DrawListOfString(BrkErrMsg, 50) ' BrkErrMsg, y End Sub Sub DrawListOfString(LofS As List(Of String), y As Integer) ' Display of Text as Graphic-Text on PictureBox With Form1.PictureBox1 : Dim sizes = {12, 9}, d = 0 Dim size As Integer Dim myFont As Font, myBrush As Brush Dim myGraphics As Graphics = .CreateGraphics Dim myFormat As New StringFormat myFormat.Alignment = StringAlignment.Center myBrush = New SolidBrush(Color.Red) : size = sizes(0) For i = 0 To LofS.Count - 1 : If i > 7 Then Exit For myFont = New Font("Verdana", size, FontStyle.Bold) myGraphics.DrawString(LofS.Item(i), myFont, myBrush, xCenter, y + d, myFormat) If i = 0 Then d += 30 : size = sizes(1) : Else d += 20 Next End With End Sub Private Function LoadImgFromDisk(xfSpec As String) As Boolean ' These possibilities, but exclude each other in use ' PictureBox1.Load(xfSpec) ' PictureBox1.Image = Image.FromFile(xfSpec) Try : Img1 = Image.FromFile(xfSpec) Catch ex As Exception : BrkErrMsg.Add("Img-File not found") : Return False End Try : Return True End Function Public Sub CopyImgToArray(ImgNr As Byte, aNr As Byte) Dim xRGB(2), w, h As Integer, pxcol As Color ' RGB is a VB-own function CopyArrayToTmp("To", aNr) If ImgNr = 1 Then w = Img1Width : h = Img1Height If ImgNr = 2 Then w = Img2Width : h = Img2Height For y = 0 To h - 1 For x = 0 To w - 1 If ImgNr = 1 Then pxcol = CType(Img1, Drawing.Bitmap).GetPixel(x, y) If ImgNr = 2 Then pxcol = CType(Img2, Drawing.Bitmap).GetPixel(x, y) ConvertToRGB(xRGB, Hex(pxcol.ToArgb)) For c = 0 To 2 : aTmp(x, y, c) = xRGB(c) : Next Next Next : CopyArrayToTmp("From", aNr) End Sub Private Sub CopyArrayToImg(aNr As Byte, ImgNr As Byte) ' RGB is a VB-own function Dim xRGB(2), w, h As Integer, ImgObj As Drawing.Bitmap = Nothing CopyArrayToTmp("To", aNr) : w = UBound(aTmp, 1) : h = UBound(aTmp, 2) If ImgNr = 1 Then ImgObj = CType(Img1, Drawing.Bitmap) If ImgNr = 2 Then ImgObj = CType(Img2, Drawing.Bitmap) For y As Integer = 0 To h - 1 For x As Integer = 0 To w - 1 For c = 0 To 2 : xRGB(c) = aTmp(x, y, c) : Next ImgObj.SetPixel(x, y, Color.FromArgb(xRGB(0), xRGB(1), xRGB(2))) Next Next If ImgNr = 1 Then Img1 = CType(ImgObj, Image) If ImgNr = 2 Then Img2 = CType(ImgObj, Image) End Sub Private Sub ConvertToRGB(ByRef xRGB() As Integer, ByVal xhex As String) Dim s As String For c = 0 To 2 : s = Mid(xhex, 2 * c + 3, 2) xRGB(c) = Convert.ToInt32(s, 16) ' 16 = convert to hex Next End Sub Private Sub DownsizeImage(v As Single) ' downsize factor in % ' in the squares of the green raster the calculation, ' shown in the following Visual-Basic-Code, delivers a medium pixel-color ' h = heiht, w = width, v = downsizefactor in % ' Xd, Yd ... pixel-coordinates of the daughter-picture ' x1, y1 ... upper left corner of a green square ' x2, y2 ... lower right corner of a green square ' r1x, r2x, r1y, r2y .... xy coordinates within a pixel (of the mother-img) ' c = 0 (for rd), c = 1 (for gn), c = 2 (for bl) Dim w = Img1Width, h = Img1Height Dim Xd, x2, x10, x20, kx, xx As Single Dim Yd, y2, y10, y20, ky, yy As Single Dim r1y, r2y, r1x, r2x As Single Dim tmp As Integer : Dim xRGB = {0, 0, 0} : If v = 0 Then Exit Sub Dim d = 100 / v : Yd = -1 : ClearImageArray(2) For y1 As Single = 0 To h - 1 Step d : Yd += 1 y2 = y1 + d : If y2 > h - 1 Then y2 = h - 1 y10 = Int(y1) : y20 = Int(y2) r1y = y1 - y10 : r2y = y2 - y20 : Xd = -1 For x1 As Single = 0 To w - 1 Step d : Xd += 1 x2 = x1 + d : If x2 > w - 1 Then x2 = w - 1 x10 = Int(x1) : x20 = Int(x2) r1x = x1 - x10 : r2x = x2 - x20 ' ---------- Square ------------ For y = y10 To y20 : ky = 1 If y = y10 Then ky = 1 - r1y If y = y20 Then ky = r2y If ky < 0 Then ky = 0 For x = x10 To x20 : kx = 1 If x = x10 Then kx = 1 - r1x If x = x20 Then kx = r2x If kx < 0 Then kx = 0 For c = 0 To 2 xRGB(c) += CInt(kx * ky * Img1Array(CInt(x), CInt(y), c)) Next Next Next : xx = x2 - x1 : yy = y2 - y1 For c = 0 To 2 : tmp = CInt(xRGB(c) / (xx * yy)) If tmp < 0 Then tmp = 0 If tmp > 255 Then tmp = 255 Img2Array(CInt(Xd), CInt(Yd), c) = tmp xRGB(c) = 0 Next ' ---------- End of the square ------------ Next Next End Sub Sub ClearImageArray(aNr As Byte) Dim w, h As Integer ', aTmp(,,) As Integer = Nothing CopyArrayToTmp("To", aNr) : w = UBound(aTmp, 1) : h = UBound(aTmp, 2) For y = 0 To h For x = 0 To w For c = 0 To 2 : aTmp(x, y, c) = 0 : Next Next Next : CopyArrayToTmp("From", aNr) End Sub End Class ' ============================================================================================== Option Strict On Option Explicit On Imports System.Drawing.Imaging Imports System.Runtime.InteropServices Public Class BitMapBitLock Public Sub CopyImgToArray(ImgNr As Integer, aNr As Byte) ' Image-Object If ImgNr = 1 Then ImageToFromArray("To", CType(Img1, Bitmap)) If ImgNr = 2 Then ImageToFromArray("To", CType(Img2, Bitmap)) aTmp = ImgArray : CopyArrayToTmp("From", aNr) End Sub Public Sub CopyArrayToImg(aNr As Byte, ImgNr As Integer) ' Image-Object CopyArrayToTmp("To", aNr) : ImgArray = aTmp Dim xbmp As Bitmap = New Bitmap(PiBxW, PiBxH) ImageToFromArray("From", xbmp) If ImgNr = 1 Then Img1 = CType(xbmp, Image) If ImgNr = 2 Then Img2 = CType(xbmp, Image) End Sub Public Sub ImageToFromArray(Mode As String, ByRef bmp As Bitmap) ' Bitmap only Dim w, h, x, y, c As Integer If Mode = "From" Then w = UBound(ImgArray, 1) + 1 : h = UBound(ImgArray, 2) + 1 bmp = New Bitmap(w, h, PixelFormat.Format24bppRgb) End If With bmp If Mode = "To" Then w = .Width : h = .Height : ReDim ImgArray(w, h, 2) Dim rect As New Rectangle(0, 0, w, h) Dim bmpData As BitmapData = .LockBits(rect, ImageLockMode.ReadWrite, .PixelFormat) Dim ptr As IntPtr = bmpData.Scan0 Dim bytes As Integer = Math.Abs(bmpData.Stride) * h Dim rgbValues(bytes - 1) As Byte Marshal.Copy(ptr, rgbValues, 0, bytes) : x = 0 : y = 0 For BytePos As Integer = 0 To rgbValues.Length - 1 Step3 For c = 0 To 2 If Mode = "To" Then ImgArray(x, y, c) = CInt(rgbValues(BytePos + 2 - c)) If Mode = "From" Then rgbValues(BytePos + 2 - c) = CByte(ImgArray(x, y, c)) Next : x += 1 : If x > w - 1 Then x = 0 : y += 1 Next : Marshal.Copy(rgbValues, 0, ptr, bytes) : .UnlockBits(bmpData) End With End Sub End Class ' ============================================================================================== | ||