Bild automatisch zuschneiden
- VB.NET
Sie verwenden einen veralteten Browser (%browser%) mit Sicherheitsschwachstellen und können nicht alle Funktionen dieser Webseite nutzen.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von FormFollowsFunction.
-
-
Ist bekannt wie breit der Rahmen ist, und ist dieser immer gleich breit?
-
Der Rahmen ist unterschiedlich breit. Im Greenshot getgreenshot.org/screenshots/ ist unter Edit/Bearbeiten => Automatisch zuschneiden diese Funktion. Leider konnte ich im Quellcode die Funktion nicht finden.
github.com/greenshot/greenshot/ -
@Goof Dann musst Du die weißen Zeilen und Spalten zählen und daraus mit der Größe des Bildes den abzuschneidenden Rand ermitteln.
Erstelle eine Bitmap der Zielgröße,
davon holst Du Dir ein Graphics-Objekt
und malst mit der richtigen Überladung vonDrawImage()
Dein Bild ohne Rand rein.
Feddich.Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
Den ersten Teil habe ich:
Dim fileName = "C:\file.jpg"
Dim CropRect As New Rectangle(100, 0, 100, 100)
Dim OriginalImage = Image.FromFile(fileName)
Dim CropImage = New Bitmap(CropRect.Width, CropRect.Height)
Using grp = Graphics.FromImage(CropImage)
grp.DrawImage(OriginalImage, New Rectangle(0, 0, CropRect.Width, CropRect.Height), CropRect, GraphicsUnit.Pixel)
OriginalImage.Dispose()
CropImage.Save(fileName)
End Using
Hier scheint es den Rest zu geben
through-the-interface.typepad.…-bitmap-more-quickly.html
Quellcode:
through-the-interface.typepad.…lipboardManager-1.0.5.zip
Wie bekomme ich das zusammen?
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices
Public Class ImageFunctions
Public Shared Function SameColor(ByVal a As Color, ByVal b As Color) As Boolean
Return (a.R = b.R And a.G = b.G And a.B = b.B)
End Function
Public Shared Function MostCommonColor(ByVal cols() As Color) As Color
' Use a dictionary to count our colors
Dim cd As Dictionary(Of Color, Integer) = _
New Dictionary(Of Color, Integer)
' Loop through the array, adding them one by one
For Each col In cols
If cd.ContainsKey(col) Then
cd.Item(col) += 1
Else
cd.Add(col, 1)
End If
Next
' Now go through the dictionary and get the
' most popular color
Dim max As Integer = 0
Dim mostCommon As Color = Color.Black
For Each kv In cd
If kv.Value > max Then
max = kv.Value
mostCommon = kv.Key
End If
Next
Return mostCommon
End Function
Public Shared Function Crop(ByVal b As Bitmap, ByVal bg As Color) As Bitmap
' Variables for the area to crop down to
Dim left As Integer = b.Width
Dim top As Integer = b.Height
Dim right As Integer = 0
Dim bottom As Integer = 0
' Indeces and the current pixel
Dim x, y As Integer
Dim c As Color
If bg = Nothing Then
' If we don't have a background passed in, get the four
' corners' colors and find the most common of them
Dim cols() As Color = { _
b.GetPixel(0, 0), _
b.GetPixel(0, b.Height - 1), _
b.GetPixel(b.Width - 1, 0), _
b.GetPixel(b.Width - 1, b.Height - 1)}
bg = MostCommonColor(cols)
End If
' Loop through each pixel
For y = 0 To b.Height - 1
For x = 0 To b.Width - 1
c = b.GetPixel(x, y)
' If it's not the same as the background color
If Not SameColor(c, bg) Then
' Then we update our variables, as appropriate
If x < left Then left = x
If y < top Then top = y
If x > right Then right = x
If y > bottom Then bottom = y
End If
Next x
Next y
' Now calculate the dimensions of the cropped output
Dim width As Integer = (right - left)
Dim height As Integer = (bottom - top)
' Add a buffer of 5% of the largest dimension (a little padding)
Dim buffer As Integer = Math.Max(width, height) * 0.05
width += 2 * buffer
height += 2 * buffer
' Create the new bitmap and the graphics object to draw to it
Dim cropped As New Bitmap(width, height)
Dim gfx As Graphics = Graphics.FromImage(cropped)
Using gfx
' Set the color of the bitmap to our background
gfx.Clear(bg)
' Draw the portion of the original image that we want to
' the new bitmap
gfx.DrawImage( _
b, New Rectangle(buffer, buffer, width, height), _
New Rectangle(left, top, width, height), _
GraphicsUnit.Pixel)
End Using
Return cropped
End Function
Public Shared Function GetPixel( _
ByVal bd As BitmapData, _
ByVal pf As PixelFormat, _
ByVal x As Integer, ByVal y As Integer) As Color
' A counter and the RGB values of our color
Dim idx, R, G, B As Integer
If pf = PixelFormat.Format16bppRgb565 Then
' Variables for the raw bytes
Dim bt1, bt2 As Byte
' Our pixels span 2 bytes - read them in
idx = (bd.Stride * y) + (2 * x)
bt1 = Marshal.ReadByte(bd.Scan0, idx)
bt2 = Marshal.ReadByte(bd.Scan0, idx + 1)
' The first five bits define R
R = ((bt1 And 245) >> 3) * 255 / 31
' Then next 6 define G
G = (((bt1 And 7) << 3) + ((bt2 And 224) >> 5)) * 255 / 63
' And the last 5 define B
B = (bt2 And 31) * 255 / 31
ElseIf pf = PixelFormat.Format32bppRgb Then
' Our pixels span 4 bytes - only the first 3 are used
idx = (bd.Stride * y) + (4 * x)
R = Marshal.ReadByte(bd.Scan0, idx)
G = Marshal.ReadByte(bd.Scan0, idx + 1)
B = Marshal.ReadByte(bd.Scan0, idx + 2)
End If
Return Color.FromArgb(R, G, B)
End Function
Public Shared Function OptiCrop( _
ByVal b As Bitmap, ByVal bg As Color) As Bitmap
' We only support 16- and 32-bit color bitmap encoding
If b.PixelFormat <> PixelFormat.Format16bppRgb565 And _
b.PixelFormat <> PixelFormat.Format32bppRgb Then
Return b
End If
' Variables for the area to crop down to
Dim left As Integer = b.Width
Dim top As Integer = b.Height
Dim right As Integer = 0
Dim bottom As Integer = 0
' Indeces and the current pixel
Dim x, y As Integer
Dim c As Color
' Lock the bitmap's memory for reading
Dim bd As BitmapData = _
b.LockBits( _
New Rectangle(New Point(), b.Size), _
ImageLockMode.ReadOnly, b.PixelFormat)
If bg = Nothing Then
' If we don't have a background passed in, get the four
' corners' colors and find the most common of them
Dim cols() As Color = { _
GetPixel(bd, b.PixelFormat, 0, 0), _
GetPixel(bd, b.PixelFormat, 0, b.Height - 1), _
GetPixel(bd, b.PixelFormat, b.Width - 1, 0), _
GetPixel(bd, b.PixelFormat, b.Width - 1, b.Height - 1)}
bg = MostCommonColor(cols)
End If
' Loop through each pixel
For y = 0 To bd.Height - 1
For x = 0 To bd.Width - 1
c = GetPixel(bd, b.PixelFormat, x, y)
' If it's not the same as the background color
If Not SameColor(c, bg) Then
' Then we update our variables, as appropriate
If x < left Then left = x
If y < top Then top = y
If x > right Then right = x
If y > bottom Then bottom = y
End If
Next x
Next y
' Unlock the bitmap's memory
b.UnlockBits(bd)
' Now calculate the dimensions of the cropped output
Dim width As Integer = (right - left)
Dim height As Integer = (bottom - top)
' Add a buffer of 5% of the largest dimension (a little padding)
Dim buffer As Integer = Math.Max(width, height) * 0.05
width += 2 * buffer
height += 2 * buffer
' Create the new bitmap and the graphics object to draw to it
Dim cropped As New Bitmap(width, height)
Dim gfx As Graphics = Graphics.FromImage(cropped)
Using gfx
' Set the color of the bitmap to our background
gfx.Clear(bg)
' Draw the portion of the original image that we want to
' the new bitmap
gfx.DrawImage( _
b, New Rectangle(buffer, buffer, width, height), _
New Rectangle(left, top, width, height), _
GraphicsUnit.Pixel)
End Using
Return cropped
End Function
End Class
Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „Goof“ ()
-
Ich habe einmal etwas gebastelt, dass dir vlt. helfen kann...
PIPP (Picture In Picture Picker)
Wenn das Bildchen sogar einen Rahmen hat und in einem homogenen Hintergrund liegt, funktioniert das sicher... -
Goof schrieb:
Wie bekomme ich das zusammen?
Sollen wir Deinen unformatierten Code, Deine Links und noch irgend was in Deinen laufenden Code konvertieren?
Strukturiere Deine Code, erstelle Unterprogramme, die einzelne Sachen abarbeiten, gib ihnen wohlklingende Namen und dann stell Deinen Code vor und erläutere die Probleme.Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
-
-
Hallo!
Hab hier noch was gefunden:
Spoiler anzeigen VB.NET-Quellcode
- Option Strict On
- Public Class Form1
- Dim _bmp As Bitmap = New Bitmap("O.bmp")
- Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
- PictureBox1.Image = _bmp
- PictureBox2.Image = _einschlRechteck(_bmp)
- End Sub
- 'Funktion - Einschliessendes Rechteck
- Public Function _einschlRechteck(ByVal _source As Bitmap) As Bitmap
- Dim __bmp As Bitmap = New Bitmap(_source.Width, _source.Height)
- Dim _minX As Integer
- Dim _maxX As Integer
- Dim _minY As Integer
- Dim _maxY As Integer
- Dim _width As Integer
- Dim _height As Integer
- Dim _lo As Integer = 0
- Dim _ro As Integer = 0
- Dim _lu As Integer = 0
- Dim _ru As Integer = 0
- _minX = _source.Width
- _maxX = 0
- _minY = _source.Height
- _maxY = 0
- _width = 0
- _height = 0
- For x = 0 To _source.Width - 1 ' links nach rechts
- For y = 0 To _source.Height - 1 'oben nach unten
- Dim _nCol As Color = _source.GetPixel(x, y) '_lockBits_A.GetPixel(x, y)
- 'If _nCol.R <> 255 AndAlso _nCol.G <> 255 AndAlso _nCol.B <> 255 Then
- If _nCol.R = 0 AndAlso _nCol.G = 0 AndAlso _nCol.B = 0 Then
- 'Einschliessendes Rechteck finden
- If y < _minY Then
- _minY = y - 2
- End If
- If y > _maxY Then
- _maxY = y + 3
- End If
- If x < _minX Then
- _minX = x - 2
- End If
- If x > _maxX Then
- _maxX = x + 2
- End If
- End If
- __bmp.SetPixel(x, y, _nCol)
- Next
- Next
- Console.WriteLine("TOP: " & _minY & " - " & "Bottom: " & _maxY & " -- " & "Left: " & _minX & " - " & "Right: " & _maxX)
- _width = _maxX - _minX
- _height = _maxY - _minY
- Using g As Graphics = Graphics.FromImage(__bmp)
- g.DrawRectangle(New Pen(Color.Red), New Rectangle(_minX, _minY, _width, _height))
- End Using
- Return __bmp
- End Function
- End Class
Zwei PictureBoxen auf eine Form und diesen Code einfügen!
..und mit den Koordinaten, also _minX, _minY, _width, _height, kannst Du das Bild dann ausschneiden bzw. neu zeichnen!Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Morrison“ ()
-
@ Morrison
Lass dasOption Strict On
bitte weg, es währe wesentlich besser, wenn TE das mal eben in der IDE erledigt.
Es wäre sogar gut, wenn sowas in jedem Thread, als erstes geklärt wird, wenn unklar !
@ Goof
Bitte mal lesen und umsetzen:
Visual Studio - Empfohlene Einstellungen
Böses aus VB6/VB2003 - und die richtigen VB.NET-Alternativen
Post #5 ist ja grauenhaft , nutze bitte das VB.Net Tag um Code ordentlich zu formatieren !
bit.ly/DotNetSearch
Code Konverter:
Online: @ developerfusion.com, @ telerik.com
Offline stand alone: Convert .NET, C# to VB Converter
VS Extensions: Convert .NET (Based on .NET 4.5), Language ConvertDieser Beitrag wurde bereits 2 mal editiert, zuletzt von „FormFollowsFunction“ ()
-
FormFollowsFunction schrieb:
Lass das Option Strict On bitte weg
Jedem das seine oder? Ich mach das auch immer oben in jeder Klasse.
Folgendes sagt google:
Spoiler anzeigen VB.NET-Quellcode
- Imports System.Drawing
- Imports System.Drawing.Drawing2D
- Imports System.Drawing.Imaging
- Imports System.IO
- Public Class ImageFunctions
- ''' <summary>
- ''' Crops the and resize image.
- ''' </summary>
- ''' <param name="img">The image</param>
- ''' <param name="targetWidth">Width of the target.</param>
- ''' <param name="targetHeight">Height of the target.</param>
- ''' <param name="x1">The position x1.</param>
- ''' <param name="y1">The position y1.</param>
- ''' <param name="x2">The position x2.</param>
- ''' <param name="y2">The position y2.</param>
- ''' <param name="imageFormat">The image format.</param>
- ''' <returns>MemoryStream of the cropped and resized image.</returns>
- Public Function CropAndResizeImage(img As Image, targetWidth As Integer, targetHeight As Integer, x1 As Integer, y1 As Integer, x2 As Integer, _
- y2 As Integer, imageFormat As ImageFormat) As MemoryStream
- Dim bmp = New Bitmap(targetWidth, targetHeight)
- Dim g As Graphics = Graphics.FromImage(bmp)
- g.InterpolationMode = InterpolationMode.HighQualityBicubic
- g.SmoothingMode = SmoothingMode.HighQuality
- g.PixelOffsetMode = PixelOffsetMode.HighQuality
- g.CompositingQuality = CompositingQuality.HighQuality
- Dim width As Integer = x2 - x1
- Dim height As Integer = y2 - y1
- g.DrawImage(img, New Rectangle(0, 0, targetWidth, targetHeight), x1, y1, width, height, _
- GraphicsUnit.Pixel)
- Dim memStream = New MemoryStream()
- bmp.Save(memStream, imageFormat)
- Return memStream
- End Function
- ''' <summary>
- ''' Resizes the image.
- ''' </summary>
- ''' <param name="img">The image</param>
- ''' <param name="targetWidth">Width of the target.</param>
- ''' <param name="targetHeight">Height of the target.</param>
- ''' <param name="imageFormat">The image format.</param>
- ''' <returns>MemoryStream of the resized image.</returns>
- Public Function ResizeImage(img As Image, targetWidth As Integer, targetHeight As Integer, imageFormat As System.Drawing.Imaging.ImageFormat) As MemoryStream
- Return CropAndResizeImage(img, targetWidth, targetHeight, 0, 0, img.Width, _
- img.Height, imageFormat)
- End Function
- ''' <summary>
- ''' Crops the image.
- ''' </summary>
- ''' <param name="img">The image</param>
- ''' <param name="x1">The position x1.</param>
- ''' <param name="y1">The position y1.</param>
- ''' <param name="x2">The position x2.</param>
- ''' <param name="y2">The position y2.</param>
- ''' <param name="imageFormat">The image format.</param>
- ''' <returns>MemoryStream of the cropped image.</returns>
- Public Function CropImage(img As Image, x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer, imageFormat As System.Drawing.Imaging.ImageFormat) As MemoryStream
- Return CropAndResizeImage(img, x2 - x1, y2 - y1, x1, y1, x2, _
- y2, imageFormat)
- End Function
- End Class
Qulle: https://dotnet-snippets.de/snippet/bilder-verkleinern-beschneiden-und-beides-gleichzeitig/1170
Das ist lediglich eine Klasse mit Funktionen zum Beschneiden eines Bildes.
Was dir nun fehlt:
Via Schleife (For) und der Funktion GetPixel ermittelst du nun noch, wie dick der Rahmen ist.
Im Anschluss, rufst du mit den ermittelten Daten einfach noch die Funktion zum Beschneiden (die ich dir oben gepostet habe) auf,
und tada, das Bild hat nun keinen Rahmen mehr.
-
@ Gather
Das Problematische daran ist, daß es dann wahrscheinlich volgendermassen ablauft:
TE Kopiert den Code ohne zu verstehen , kopiert sich morgen woandersStrict Off
Code und kreutzt hier dann übermorgen wieder damit auf.
Daher scheint mir das nicht Sinvoll zu sein.bit.ly/DotNetSearch
Code Konverter:
Online: @ developerfusion.com, @ telerik.com
Offline stand alone: Convert .NET, C# to VB Converter
VS Extensions: Convert .NET (Based on .NET 4.5), Language Convert
-
Benutzer online 1
1 Besucher
-
Ähnliche Themen
-
lris08 - - Sonstige Problemstellungen
-
Pes1899.vb - - Sonstige Problemstellungen
-
7 Benutzer haben hier geschrieben
- Goof (4)
- RodFromGermany (2)
- Gather (2)
- FormFollowsFunction (2)
- VB1963 (1)
- ThuCommix (1)
- Morrison (1)