there is a folder named "1"
"1" folder has around 1-100 image files in there
example file name: 000001.jpg 0000012.jpg 0000013.jpg ---> 000100.jpg
i want to combine all image from that folder (named 1)
and extract to one file (output_1.jpg) from 100 file to 1 file (Vertical)
but if there is 10 folder, combine all image from folder 1,2,3.....
and extract to one file per folder
output_1.jpg (all image from folder 1)
output_2.jpg (all image from folder 2)
output_3.jpg (all image from folder 3)
and more
folder structure:
-----c:\
----------folder1\
---------------------000001.jpg
---------------------000002.jpg
the combined image file will be extract to c:\ (not in folder1 or 2 or 3....)
this is my code, i have to add more code file by file to combine them (headache attack)
Dim Img1 As Bitmap = Image.FromFile("C:\1\000001.jpg")
Dim Img2 As Bitmap = Image.FromFile("C:\1\000002.jpg")
Dim Img3 As Bitmap = Image.FromFile("C:\1\000003.jpg")
Dim Img4 As Bitmap = Image.FromFile("C:\1\000004.jpg")
Dim Img5 As Bitmap = Image.FromFile("C:\1\000005.jpg")
Dim extract_img As Bitmap
Dim Width As Integer
Dim Height As Integer
Dim x As Integer
Dim y As Integer
If Img1.Width > Img2.Width Then
Width = Img1.Width
Else
Width = Img2.Width
End If
Height = Img1.Height + Img2.Height + Img3.Height + Img4.Height + Img5.Height
extract_img = New Bitmap(Width, Height)
For x = 0 To Img1.Width - 1
For y = 0 To Img1.Height - 1
extract_img.SetPixel(x, y, Img1.GetPixel(x, y))
Next
Next
For x = 0 To Img2.Width - 1
For y = 0 To Img2.Height - 1
extract_img.SetPixel(x, y + Img1.Height, Img2.GetPixel(x, y))
Next
Next
For x = 0 To Img3.Width - 1
For y = 0 To Img3.Height - 1
extract_img.SetPixel(x, y + Img1.Height + Img2.Height, Img3.GetPixel(x, y))
Next
Next
For x = 0 To Img4.Width - 1
For y = 0 To Img4.Height - 1
extract_img.SetPixel(x, y + Img1.Height + Img2.Height + Img3.Height, Img4.GetPixel(x, y))
Next
Next
For x = 0 To Img5.Width - 1
For y = 0 To Img5.Height - 1
extract_img.SetPixel(x, y + Img1.Height + Img2.Height + Img3.Height + Img4.Height, Img5.GetPixel(x, y))
Next
Next
extract_img.Save("C:\output.jpg", System.Drawing.Imaging.ImageFormat.Jpeg)
You can get the image sizes from each file and work out how large the final image will be.
Then, as pointed out in a comment , you need to check that the final size is not too large.
Make a new bitmap to contain them all, then iterate over the files to draw them into the big one.
Finally, wrap it all up in an iteration over the subdirectories, something like this:
Imports System.Drawing.Imaging
Imports System.IO
Public Class Form1
Function GetImageSize(fileName As String) As SizeF
' From "Getting image dimensions without reading the entire file"
' https://stackoverflow.com/questions/111345/getting-image-dimensions-without-reading-the-entire-file
Dim dims As SizeF
Using fs As New FileStream(fileName, FileMode.Open, FileAccess.Read)
Using img = Image.FromStream(fs, False, False)
dims = New SizeF(img.PhysicalDimension.Width, img.PhysicalDimension.Height)
End Using
End Using
Return dims
End Function
Function GetOverallImageSize(srcDir As String) As Size
Dim largestWidth As Single
Dim overallHeight As Single
For Each f In Directory.EnumerateFiles(srcDir, "*.jpg")
Dim dims = GetImageSize(f)
largestWidth = Math.Max(largestWidth, dims.Width)
overallHeight += dims.Height
Next
Return New Size(CInt(largestWidth), CInt(overallHeight))
End Function
Sub MakeSprites(rootDir As String)
For Each srcDir In New DirectoryInfo(rootDir).EnumerateDirectories
Dim overallSize = GetOverallImageSize(srcDir.FullName)
If overallSize.Width = 0 OrElse overallSize.Height = 0 Then
MsgBox("No suitable image files found in " & srcDir.FullName)
Continue For
End If
If overallSize.Width > 32767 OrElse overallSize.Height > 32767 Then
MsgBox("Combined size of " & overallSize.ToString() & " is too large in " & srcDir.Name)
Continue For
End If
Using bmp As New Bitmap(overallSize.Width, overallSize.Height, PixelFormat.Format24bppRgb)
Dim g = Graphics.FromImage(bmp)
Dim y = 0
For Each f In Directory.EnumerateFiles(srcDir.FullName, "*.jpg")
Using im = Image.FromFile(f)
g.DrawImage(im, 0, y)
y += im.Height
End Using
Next
bmp.Save(Path.Combine(rootDir, srcDir.Name & ".png"), ImageFormat.Png)
End Using
Next
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim rootDir = "C:\temp\sprites"
MakeSprites(rootDir)
End Sub
End Class
So from this directory content:
I got the file "1.png":
If you really want to save the end result as a JPEG, you will probably want to read How to: Set JPEG Compression Level because the default is less than good quality. You would need to add
Private Shared Function GetEncoder(ByVal format As ImageFormat) As ImageCodecInfo
Dim codecs As ImageCodecInfo() = ImageCodecInfo.GetImageDecoders()
Dim codec As ImageCodecInfo
For Each codec In codecs
If codec.FormatID = format.Guid Then
Return codec
End If
Next codec
Return Nothing
End Function
and modify MakeSprites
to be
Sub MakeSprites(rootDir As String)
Dim jpegEncoder As ImageCodecInfo = GetEncoder(ImageFormat.Jpeg)
Dim myEncoder As Imaging.Encoder = Imaging.Encoder.Quality
Dim myEncoderParameters As New EncoderParameters(1)
Dim myEncoderParameter As New EncoderParameter(myEncoder, 85L)
myEncoderParameters.Param(0) = myEncoderParameter
For Each srcDir In New DirectoryInfo(rootDir).EnumerateDirectories
Dim overallSize = GetOverallImageSize(srcDir.FullName)
If overallSize.Width = 0 OrElse overallSize.Height = 0 Then
MsgBox("No suitable image files found in " & srcDir.FullName)
Continue For
End If
If overallSize.Width > 32767 OrElse overallSize.Height > 32767 Then
MsgBox("Combined size of " & overallSize.ToString() & " is too large in " & srcDir.Name)
Continue For
End If
Using bmp As New Bitmap(overallSize.Width, overallSize.Height, PixelFormat.Format24bppRgb)
Dim g = Graphics.FromImage(bmp)
Dim y = 0
For Each f In Directory.EnumerateFiles(srcDir.FullName, "*.jpg")
Using im = Image.FromFile(f)
g.DrawImage(im, 0, y)
y += im.Height
End Using
Next
bmp.Save(Path.Combine(rootDir, srcDir.Name & ".jpg"), jpegEncoder, myEncoderParameters)
End Using
Next
End Sub
You should be disappointed with the result - especially at the borders between images. It's just down to how JPEG-encoding works.
You will probably want to add some Try...Catches too for when things go wrong. And the MakeSprites
method should probably be a function which returns a list of the problems it encountered rather than showing message boxes itself.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.