Mnozí jste se již jistě setkali s e-shopem, ve kterém byly obrázky označeny vodoznakem. V dnešní době se tato technika stáva trendem pro zabezpečování autorských práv na fotky. Nebudeme si nic nalhávat a uznáme, že výroba opravdu profesionálních fotografií není příliš levnou záležitostí. Naučíme se tedy, jak vytvořit jednoduchou utilitku, pomocí které budeme schopni naše fotky hromadně upravit.
Nejprve si vytvoříme novou aplikaci, na jejíž hlavním okně sestavíme následující komponentové rozhraní:
Program bude fungovat tak, že si nejprve otevřeme obrázky, které chceme upravit. Jejich celkový seznam bude zobrazen v ListBoxu. Následně potřebujeme načíst soubor obrázku vodoznaku. Tudíž ho vykreslíme na všechny načtené obrázky v ListBoxu. Samozřejmě potřebujeme vědět, kam vodoznak vykreslit. Pro tento účel použijeme výběrovou nabídku níže. Aby jsme lépe specifikovali umístění pro hromadnou operaci se soubory, které mohou mít různé velikosti, určujeme vždy relativní pozici od určitého rohu. Přepsání původních souborů se stává též velmi užitečnou pomůckou.
Aby jsme docílili efektu vodoznaku, používáme vykreslení jednoho obrázku přez druhý, za použití transparence. Za předpokladu, že chceme docílit lepšího vzhledu, tedy textu s průhledným okolím, tak použijeme soubor s podporou průhlednosti, například *.png nebo *.gif.
Ukázka výsledného obrázku za použití souboru PNG:
Pokud budeme po přidání vodoznaku soubory umisťovat na web, využijeme kompresi do formátu JPEG.
Tak a teď už se pusťme do vlastního psaní programu. Nejdříve vytvoříme několik proměnných, které slouží jako centrální úložistě nastavení pro kompresi obrázků:
Public JPGEncoder As Drawing.Imaging.Encoder
Public JPGCodecInformations As Drawing.Imaging.ImageCodecInfo
Public JPGEncoderParameters As New Drawing.Imaging.EncoderParameters(1)
Public CompressionQuality As Integer = 80
Dále sestavíme několik procedur, které pak můžeme používat i v rozsáhlejších projektech. Budou nám sloužit jako centrální úpravny pro obrázky.
Správa komprese obrázků:
Public Sub SetJPGCompression()
JPGEncoderParameters.Param(0) = New Drawing.Imaging.EncoderParameter(Imaging.Encoder.Quality, CLng(CompressionQuality))
JPGCodecInformations = GetEncoderInfo("image/jpeg")
End Sub
Private Function GetEncoderInfo(ByVal mimeType As String) As ImageCodecInfo
Dim i As Integer
Dim encoders As ImageCodecInfo()
encoders = ImageCodecInfo.GetImageEncoders()
For i = 0 To encoders.Length
If encoders(i).MimeType = mimeType Then
Return encoders(i)
End If
Next
Return Nothing
End Function
Načtení obrázku ze souboru:
Nezbytně též potřebujeme vytvořit funkci, která načte ze souboru obrázek tak, aby nebyl soubor nijak svázán s výslednou proměnnou. Tato technika využívá načtení ze souboru do proměnné Image, pak vytvoření proměnné Bitmap se stejnou velikostí jako načtený Image. Následně vytvoříme objekt Graphics, který propojíme s proměnnou Bitmap a pak zde vykreslíme načtený obrázek. Nakonec uvolníme proměnnou Image.
Public Function LoadImage(ByVal FileName As String) As Image
Try
Dim i As Image = Image.FromFile(FileName)
Dim img As Bitmap = New Bitmap(i.Width, i.Height)
Dim g As Drawing.Graphics = Drawing.Graphics.FromImage(img)
g.DrawImage(i, 0, 0, i.Width, i.Height)
i.Dispose()
Return img
Catch ex As Exception
MsgBox("Nastala chyba při načítání obrázku." & vbCrLf & "(" & ex.Message & ")", MsgBoxStyle.Critical, "Chyba")
Return Nothing
End Try
End Function
Vytvoření souboru s vodoznakem:
Private Sub CreateImageFile(ByVal InputFileName As String, ByVal OutputFileName As String, ByVal ImgPos As Point, ByVal Opacity As Integer)
Try
Dim img As Image = LoadImage(InputFileName)
Dim vod As Image = LoadImage(VFileName)
Dim g As Graphics = Graphics.FromImage(img)
Dim ptsArray As Single()() = {New Single() {1, 0, 0, 0, 0}, _
New Single() {0, 1, 0, 0, 0}, _
New Single() {0, 0, 1, 0, 0}, _
New Single() {0, 0, 0, Math.Round(Opacity / 100, 2), 0}, _
New Single() {0, 0, 0, 0, 1}}
Dim clrMatrix As New ColorMatrix(ptsArray)
Dim imgAttributes As New ImageAttributes
imgAttributes.SetColorMatrix(clrMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap)
g.DrawImage(vod, New Rectangle(ImgPos, vod.Size), 0, 0, vod.Width, vod.Height, GraphicsUnit.Pixel, imgAttributes)
img.Save(OutputFileName, Me.JPGCodecInformations, Me.JPGEncoderParameters)
Catch ex As Exception
MsgBox("Nastala chyba při úpravách pro vložení nového obrázku!" & vbCrLf & "(" & ex.Message & ")", MsgBoxStyle.Critical, "Chyba")
End Try
End Sub
Teď, když už máme hotové jádro naší aplikace, můžeme se pustit do nastavení ovládacích prvků, tedy tlačítek.
Tlačítko "Přidat obrázky, které se mají upravit":
Private Sub PridatObrazkyProUpravu_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PřidatObrázkyProÚpravu.Click
If Soubory.ShowDialog = Windows.Forms.DialogResult.OK Then
For Each f As String In Soubory.FileNames
ListBox1.Items.Add(f)
Next
End If
End Sub
Tlačítko "Smazat seznam":
Private Sub SmazatSeznamObrazku_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SmazatSeznamObrázků.Click
ListBox1.Items.Clear()
End Sub
Tlačítko "Nahrát soubor vodoznaku":
Private Sub NahratSouborVodoznaku_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NahrátSouborVodoznaku.Click
Vodoznak.FileName = VFileName
If Vodoznak.ShowDialog = Windows.Forms.DialogResult.OK Then
VFileName = Vodoznak.FileName
End If
End Sub
Tlačítko "Spracuj soubory!":
Private Sub SpracujSoubory_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SpracujSoubory.Click
Dim f As String
Dim imgPos As New Point(0, 0)
Dim Opc As Integer = Opacityx.Value
Dim img As Image
Dim imgVod As Image
CompressionQuality = Comp.Value
SetJPGCompression()
If VFileName.Length > 0 Then
If IO.File.Exists(VFileName) Then
imgVod = LoadImage(VFileName)
If ListBox1.Items.Count > 0 Then
For i As Integer = 0 To ListBox1.Items.Count - 1
If IO.File.Exists(ListBox1.Items.Item(i)) Then
f = ListBox1.Items.Item(i)
img = LoadImage(f)
If TopLeft.Checked Then
imgPos.X = TopLeftX.Value
imgPos.Y = TopLeftY.Value
End If
If TopRight.Checked Then
imgPos.X = img.Width - TopRightX.Value - imgVod.Width
imgPos.Y = TopRightY.Value
End If
If BottomLeft.Checked Then
imgPos.X = BottomLeftX.Value
imgPos.Y = img.Height - BottomLeftY.Value - imgVod.Height
End If
If BottomRight.Checked Then
imgPos.X = img.Width - BottomRightX.Value - imgVod.Width
imgPos.Y = img.Height - BottomRightY.Value - imgVod.Height
End If
If RewriteOriginal.Checked Then
CreateImageFile(f, f, imgPos, Opc)
Else
CreateImageFile(f, f.Substring(0, f.LastIndexOf("\") + 1) & CStr(i) & ".jpg", imgPos, Opc)
End If
Else
MsgBox("Soubor " & ListBox1.Items.Item(i) & " neexistuje!", MsgBoxStyle.Critical, "Chyba")
End If
Next
MsgBox("Spracování proběhlo úspěšně!", MsgBoxStyle.Information, "Informace")
Else
MsgBox("Nejsou vybrány soubory pro spracování!", MsgBoxStyle.Exclamation, "Upozornění")
End If
Else
MsgBox("Soubor vodoznaku neexistuje!", MsgBoxStyle.Critical, "Chyba")
End If
Else
MsgBox("Nebyl vybrán soubor s vodoznakem!", MsgBoxStyle.Exclamation, "Upozornění")
End If
End Sub
Váš program jest vytvořen, nezbývá než popřát štěstí při jeho používání. Zdrojový kód příkladu si můžete stáhnout
.