 |
|
|
 |
|
|
 |
|
 |
Thanks for putting this up i have found it really useful in handling large amounts of photos i seem to hoard!
I have added the below as i often resize images to set pixel widths for displaying well on websites or for importing into documents and thought it may be useful for others,
try not to laugh too much i've not touched VB for about a year!
lblcPix.Text = img.Size.Width
Dim NewPix As Single
Dim OrigPix As Single
OrigPix = img.Size.Width
NewPix = txtPixNew.Text
txtRedFactor.Text = NewPix / OrigPix
|
|
|
|
 |
|
 |
Thanx man..! Its perfect fit to my need..
|
|
|
|
 |
|
|
 |
|
 |
I have to create thumbnails of 140 pictures I've taken for my church, and this app saved me a ton of time -- it did it all for me in a couple minutes. Thanks for posting it!
|
|
|
|
 |
|
 |
Hi, I'm really pleased by this article. It is clear and and provides excellent information via Alberto's replies to valid feeback. It's also quite a nifty and lightweight little app. 5/5
Now, How can I make is recurse subdirectories?
For example, my camera takes the images with a specific date, and places each in a folder with the date of that image inside My pictures:
My Documents/My Pictures/01/01/2010/012345.jpg
I want to select ..\My Pictures\ as the source, and resize every image within, no matter sub directory the images are inside.
What code do I need to add?
Thanks in advance
Rob
|
|
|
|
 |
|
 |
What you basically need is to repeat the computations done inside the btnGo_Click() event handler (that apply to a single folder) for any subfolder found in the initial input path, then recursively call the same modified procedure for all nodes of the subfolder structure.
Conceptually, in pseudocode you need to change this:
Private Sub btnGo_Click(...)
Do something on txtINpath.Text
End Sub
into this:
Private Sub btnGo_Click(...)
Call ScanDir(txtINpath.Text)
End Sub
Private Sub ScanDir(Path)
Do something on Path
For each subdirectory of Path
Call ScanDir(a subdir of Path)
Next
By translating this into practice, the following code should do the work (I did't test it yet... it's up to you):
Private Sub btnGo_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnGo.Click
If Not Directory.Exists(txtINpath.Text) Or _
Not Directory.Exists(txtOUTpath.Text) Then
MessageBox.Show("The folder...", "Error", _
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Exit Sub
End If
ScanDir(txtINpath.Text)
End Sub
Private Sub ScanDir(ByVal Path As String)
Dim fs As String() = Directory.GetFiles(Path, "*.jpg")
Dim Ffull, Fshort As String
For Each Ffull In fs
FromFile(Ffull)
Application.DoEvents()
Fshort = Ffull.Substring(Ffull.LastIndexOf("\") + 1)
lblName.Text = Fshort
Application.DoEvents()
Dim dr As DialogResult
If chkBatchProc.Checked Then
dr = DialogResult.Yes
Else
dr = MessageBox.Show("Convert?", Fshort, _
MessageBoxButtons.YesNoCancel)
End If
If dr = DialogResult.Cancel Then
Exit For
ElseIf dr = DialogResult.Yes Then
Reduce(Double.Parse(txtRedFactor.Text, _
New System.Globalization.CultureInfo("EN-us")))
Application.DoEvents()
ToFile(txtOUTpath.Text & "\" & Fshort)
End If
Next
Dim f As String
Dim paths As String() = Directory.GetDirectories(Path)
For Each f In paths
ScanDir(f)
Next
End Sub
Of course, in this example, the output path will be the same for all the generated pictures (resulting in a flattened folder structure in the generated output).
If this is not the desired behavior, and you need to preserve in the output result the folder structure of the source input pictures tree, you will have to modify the call to "ToFile(...)" in order to use a destination folder that contains the desired substring path of the input folder.
Hope this helps.
Cheers, AV
|
|
|
|
 |
|
 |
hi There,
Excellent code yar!.
Thanks and Regards,
Hardik Darji.
|
|
|
|
 |
|
 |
Hii
This is Abdul Zamrood from Chicago USA. I'm currently a student in MSIT program.Image resizer is a very handy tool.I really appreciate the work done. I need a complete document about how to built this appication or tool and how to proceed with each step. Please help me out. I would really appreciate it. If possible..please mail the document to my mail... abdulzamrood@gmail.com
Thank You.
regards
|
|
|
|
 |
|
 |
Hi Abdul.
I have no time to write down a document on that, but you have to consider the following:
- the Image Batch Resizer is a very simple one-form Windows Forms Application written in VB.NET
- the user interface composition is trivial (some labels, some textboxes, a checkbox and an image control): you should be able to create it from scratch if you learnt the basics of UI design on any "hello world" tutorial for VB.NET (for example, try these articles: http://www.informit.com/articles/article.aspx?p=21418&seqNum=4[^] and http://www.vbdotnetheaven.com/UploadFile/mahesh/WindowsForms04222005065808AM/WindowsForms.aspx[^])
- also the logic to be attached to the buttons for selecting folders is very easy and (in my opinion) the code is self-explanatory
- the only "difficult" part could be in managing images through the Bitmap class of the .NET class library, but about this the MSDN documentation gives you more than any document I could write.
Hope this helps.
Regards, AV
|
|
|
|
 |
|
 |
THANX Mr. Alberto Venditti.. I appreciate that.
|
|
|
|
 |
|
 |
How do I set the height to a definite size and keep the width proportionate with the original?
|
|
|
|
 |
|
 |
Hi.
In order to set a specific height for resulting images (while mantaining the original aspect ratio), you basically have to modify the Reduce() subroutine.
Currently, this procedure receives a reducing factor and applies it to Height/Width of output images:
img = New Bitmap(img, New Size(img.Size.Width * factor, img.Size.Height * factor))
If you could supply a fixed "height" instead of a "factor", you could write:
img = New Bitmap(img, New Size(img.Size.Width * (height / img.Size.Height), height))
(that is: your reducing factor is now the ratio between the target haight and the original height)
So, if you want to minimize the modification to the code, you could:
- consider the "factor" variable and the txtRedFactor textbox actually as the image target height;
- rename the label for the txtRedFactor so that the user understand it *is* the image target height
- change this line:
img = New Bitmap(img, New Size(img.Size.Width * factor, img.Size.Height * factor))
in:
img = New Bitmap(img, New Size(img.Size.Width * (factor / img.Size.Height), factor))
Hope this helps (and this works, because I did't try it directly... ).
Cheers, AV
|
|
|
|
 |
|
 |
I really didn`t try it but it looks like it would work.
I was playing around with it this morning and modified the reduce sub to:
img = New Bitmap(img, New Size(img.Width / txtRedFactor.Text, img.Height / txtRedFactor.Text)).
This works if you use a whole number instead of a decimal and you don`t have to modify anything else.
Thanks for the reply anyway and I`ll try yours and let you know how it works out.
Thanks, Marty
|
|
|
|
 |
|
 |
Well,
to me your solution appears quite identical to the original code: you are just dividing Width and Height by a factor instead of multiplying them by a factor.
img = New Bitmap(img, New Size(img.Width / txtRedFactor.Text, img.Height / txtRedFactor.Text))
img = New Bitmap(img, New Size(img.Size.Width * factor, img.Size.Height * factor))
While your initial question was "set a definite Height and keep Width proportionate", which is different: it implies determining the factor by old and new Height.
Another quick note: I think your solution works only with integer number (and not with fractional numbers) just because you're doing math between numbers and strings (which is a quite disputable thing...), so VB.NET is trying to implicitly cast txtRedFactor.Text to a number.
Cheers, AV
|
|
|
|
 |
|
 |
Hi
I am using this code for resize pic. But when i tried to resize more then 5 MB pic it show out of memory in this line:
img = New Bitmap(img, New Size(img.Size.Width * factor, img.Size.Height * factor))
Can you give me any advice.
My email address:sisprog@yahoo.com
Please reply as soon as...
Thanks
Shaiful
|
|
|
|
 |
|
 |
Hi.
Was that image inside a batch of lots of big images? If yes, you could try to run the Resizer on a smaller batch containing (eventually only) that specific picture. If the issue doesn't persist, then it was probably due to some missing disposing of Bitmap resources.
Currently, in order to show the resizing in progress, the tool shows in picPhoto.Image the image currently being processed. It should be disposed just before it is discarded by the next one in this line:
picPhoto.Image = img
AV
|
|
|
|
 |
|
 |
Hi
This image size is 66.3MB its just normal photo.
Can you give me any advice in code? I dont understand where i wanna to change in code
Thanks
Shaiful
|
|
|
|
 |
|
 |
First of all, please, try to put your image alone in the "input folder", then open the Resizer tool and run it.
If it still fails, then the problem is not in a missing disposal of memory resources but in their allocation, so I'll start to suppose the issue is not in the program, but in the fact that your picture is really really huge.
AV
|
|
|
|
 |
|
 |
Hi!
Awesome work, but one thing bothers me, what is this Ffull string youre using? I cant see it being set at any point. So would you explain this:
For Each Ffull In fs
FromFile(Ffull)
Application.DoEvents()
Fshort = Ffull.Substring(Ffull.LastIndexOf("\") + 1)
Particularly those things with Ffull. I just need some info 'cause I'm gonna do a script that also puts them in numbered order.
Thanks in advance
EDIT: Nevermind, already got it. Heres my code:
Dim Ffull, Fshort As String
Dim n As Integer = 0
For Each Ffull In fs
n = n + 1
FromFile(Ffull)
Application.DoEvents()
box1.Text = Ffull
Fshort = Ffull.Substring(Ffull.LastIndexOf("\") + 1)
lblName.Text = Fshort
Application.DoEvents()
Dim dr As DialogResult
If chkBatchProc.Checked Then
dr = DialogResult.Yes
Else
dr = MessageBox.Show("Convert?", Fshort, MessageBoxButtons.YesNoCancel)
End If
If dr = DialogResult.Cancel Then
Exit For
ElseIf dr = DialogResult.Yes Then
Reduce(Double.Parse(txtRedFactor.Text, New System.Globalization.CultureInfo("EN-us")))
Application.DoEvents()
ToFile(txtOUTpath.Text & "\" & n & ".jpg")
End If
Next
modified on Wednesday, July 2, 2008 11:06 AM
|
|
|
|
 |
|
 |
Fine. You eventually were not used to use ForEach loops.
Regards, AV
|
|
|
|
 |
|
 |
I added to the Reduce subroutine the ability to send the desired width and height.
Private Sub Reduce(ByVal width As Integer, ByVal height As Integer)
img = New Bitmap(img, New Size(width, height))
picPhoto.Image = img
Dim SizeKb As String
' To compute: size in Kb
Dim ms As New MemoryStream()
img.Save(ms, Imaging.ImageFormat.Jpeg)
SizeKb = (ms.Length \ 1024).ToString() & "Kb "
lblCurrentSize.Text = "Current Size: " & SizeKb & "(" & img.Width & "x" & img.Height & ") [" & img.Width / img.Height & "]"
End Sub
So that's how I got this thumbnail:
Link to affected JPEG thumbnail
Won't show in IE.
Shows in Windows Explorer and FrontPage editing browser.
Shows in Picture Viewer.
Half of it shows in Firefox.
GIMP was the only app that gave a clue - it says:
"JPEG image message / Premature end of JPEG file / EXIF data will be ignored."
Then GIMP shows it just fine.
When I run a batch, about 90% of the thumbnails are affected this way; 10% work with no problems.
Example:
Link to few more examples
Have any idea why this "Premature end of JPEG file" happens? Or how it can be fixed?
Thanks!
Buffbuh
|
|
|
|
 |
|
 |
Did you try to do some modifications in the actual saving of file as described in the post titled "Size difference on web page"?
AV
|
|
|
|
 |
|
 |
Hi there,
Many thanks for a very useful tool. I've added two lines in your code that made this even more useful for me.
In your frmMain.vb file, below line
Fshort = Ffull.Substring(Ffull.LastIndexOf("\") + 1)
I added the following two lines
Dim Fshort2() As String = Fshort.Split(".")
Fshort = String.Concat(Fshort2(0), "_s.", Fshort2(1))
These two lines add two extra characters (_s) before the picture extension (e.g. jpg, gif ar any other).
Result: if the original picture name is "picture.jpg" the name of the small one is "picture_s.jpg"
That was useful for a project that I work so I thought to share this with you guys.
Thanks again for a useful idea.
PlouVou
|
|
|
|
 |