Discussion:
VB6 Image Resizer
(too old to reply)
GS
2020-03-28 04:26:06 UTC
Permalink
Hi All,
I've been searching for ideas on how to manage batch resizing of images in a
VB6.exe explorer app, but not finding much. I have the explorer part already
done; - it has been working well for the past 10+ years. I need some guidance
with how to batch resize a selection of image files (all are JPG format) in the
Fileview pane. (It's configured to list files only)

Thanks in advance for all/any assistance!
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
Mayayana
2020-03-28 14:04:29 UTC
Permalink
"GS" <***@v.invalid> wrote

| I've been searching for ideas on how to manage batch resizing of images in
a
| VB6.exe explorer app, but not finding much.

I don't know if this will be what you want, but
I've needed to do that in the past for an Explorer
Bar. I also did it with a script-based HTA image
viewer, but that one just uses IE to resize (which
works surprisingly well).

A couple of things:

https://www.jsware.net/jsware/vbcode.php5#jpgthumbs

That has two projects. One extracts JPG thumbnails.
The other is code for turbojpeg, the best, fastest method
I could find to resize very large JPSs in order to create
a thumbnail. For basic resizing of a bitmap... that's a whole
other topic.
My approach was trying to get a thumbnail as fast as
possible to display in the Bar when an image file is selected.
A thumbnail is clearly fastest, but not always available.
So I was using a combination of methods.

Here's a VBScript version that can extract either JPG or
RGB versions of JPG thumbnails. It could be adapted for
VB:

https://www.jsware.net/jsware/scrfiles.php5#jpginf

(Little known fact: Most thumbnails in JPGs are JPGs,
but they can also be BMPs or an obscure 3rd type. This
script can extract the first two.)

You can also do all sorts of things with WIA. The syntax
of functions is horrendous, but the help provides samples.
If I remember correctly, though, it's actually quite slow.
But here's my HTA image editor that uses it:

https://www.jsware.net/jsware/scrfiles.php5#wiaed

This is the gist of the resize function, assuming you
already have the objects set up.

Set ImProc = CreateObject("WIA.ImageProcess")

Set ImgFile = CreateObject("WIA.ImageFile")

'--clear out all filters:
While (ImProc.Filters.Count > 0): ImProc.Filters.Remove 1: Wend
'-- add the resize filter:
ImProc.Filters.Add ImProc.FilterInfos("Scale").FilterID
'-- set sizes:
ImProc.Filters(1).Properties("MaximumWidth") = SelWidth
ImProc.Filters(1).Properties("MaximumHeight") = SelHeight
ImProc.Filters(1).Properties("PreserveAspectRatio") = True
Set ImgFile = ImProc.Apply(ImgFile)

You can use that in VB. WIA can do a lot of things. But
MS seem to have put some kind of halfwit in charge of
designing and implementing it. I don't really get the point
of it, aside from the scanner interface it introduced.

You might also be able to somehow hijack whatever IE is
using to resize. It does a beautiful job, very fast. Since you're
re-inventing the wheel there's no reason not to reuse the rim. :)
Arne Saknussemm
2020-03-28 16:17:31 UTC
Permalink
It was Sat, 28 Mar 2020 10:04:29 -0400 when
Post by Mayayana
(Little known fact: Most thumbnails in JPGs are
JPGs, but they can also be BMPs or an obscure 3rd
type. This script can extract the first two.)
In file... yes, but when "rendered" (which also
includes rendered on a NON VISIBLE device context),
all images will be DIB images (Device Independed
Bitmaps) then they may be stored using whatever
format you want, but after you load them into a
windows DC (be it a memory area, a window, a
printer or whatever else) they'll always be DIB, this
eases the task of handling images since the APIs will
always use and deal with the same format, makes a lot
of sense, and should be taken into account
Mayayana
2020-03-28 18:12:44 UTC
Permalink
"Arne Saknussemm" <***@spamgourmet.com> wrote

| > (Little known fact: Most thumbnails in JPGs are
| > JPGs, but they can also be BMPs or an obscure 3rd
| > type. This script can extract the first two.)
|
| In file... yes, but when "rendered" (which also
| includes rendered on a NON VISIBLE device context),
| all images will be DIB images (Device Independed
| Bitmaps) then they may be stored using whatever
| format you want, but after you load them into a
| windows DC (be it a memory area, a window, a
| printer or whatever else) they'll always be DIB, this
| eases the task of handling images since the APIs will
| always use and deal with the same format, makes a lot
| of sense, and should be taken into account
|

I'm not sure what your point is. I'm just talking about
getting thumbnails out of the JPG header. They're
in there as small files. Getting a thumbnail will always be
much faster than resizing to thumbnail, when a thumbnail
is available. So you extract the JPG thumbnail, then load
that into whatever image display.

But once you decide to do that you need to be aware
that while most tumbnails are JPG, they can actually be
3 formats. I wrote code to check the type and take out
a JPG thumbnail file or uncompressed RGB data. I've only
seen the latter once or twice. I've never seen the third type
and haven't written code to extract it.
Mayayana
2020-03-28 18:43:48 UTC
Permalink
I maybe should have explained that: One can't
just extract a thumbnail and load it into a
picturebox. A JPG thumbnail is, in fact, an actual
file. But uncompressed RGB thumbnails are in reverse
byte order and have no header. So the bytes have
to be reversed. Then a header has to be created.
Only then do you have a file that can be loaded.

(I know there are top-down and bottom-up bitmaps.
I don't remember which is which. I just remember
that when I extracted the RGB bytes I had to store
them in the file in reverse.)

There are also other ways the thumbnail can be stored
in the header. As far as I know, only the JPG version
is stored as an entire file that can be rreconstituted by
simply writing the bytes to disk.
Arne Saknussemm
2020-03-29 13:48:26 UTC
Permalink
It was Sat, 28 Mar 2020 14:43:48 -0400 when
Post by Mayayana
I maybe should have explained that: One can't
just extract a thumbnail and load it into a
picturebox. A JPG thumbnail is, in fact, an actual
file. But uncompressed RGB thumbnails are in reverse
byte order and have no header. So the bytes have
to be reversed. Then a header has to be created.
Only then do you have a file that can be loaded.
My point is that Windows GDI APIs work on DIBs, those
are an in-memory representation of an image which may
then be stored to (or retrieved from) whatever
format, be it JPG, PNG or whatever, such formats are
just STORAGE formats, so instead of focusing on how a
given image is stored, it would be a better idea to
focus on how to quickly render it, then, to retrieve
the image from storage and decode it, there are a
bunch of libraries and APIs, so that shouldn't be a
big issue, nor it would be how the image is stored,
once you load and decode it from storage, you'll have
a DIB and that's all you need to show/manipulate it,
no need to worry about orientation/format/whatever
Mayayana
2020-03-29 14:41:18 UTC
Permalink
"Arne Saknussemm" <***@spamgourmet.com> wrote

| My point is that Windows GDI APIs work on DIBs, those
| are an in-memory representation of an image which may
| then be stored to (or retrieved from) whatever
| format, be it JPG, PNG or whatever, such formats are
| just STORAGE formats, so instead of focusing on how a
| given image is stored

You seem to have misunderstood. We all know a raster
image is a bitmap. We all know about DIBs. We all know
raster image formats are various ways to store various kinds
of bitmaps. What I was talking about is the process of
getting thumbnails from a JPG.

Say you have a 12 MB JPG. To make a thumbnail of that
is difficult to do quickly. If you have 30 of them it's going
to be very slow. So if they have embedded thumbnails in
the EXIF data that will be a much quicker solution. Virtually
instant to process 30 files. Those thumbnails are typically
something like 160x100. But to extract them you have to
know how they're stored, and that can be in several formats.
So you read the EXIF header data, look for a thumbnail,
check the numeric flag that tells you what type it is, and
if it's a type you're prepared to extract then you extract
the bytes. If it's JPG then you'll have extracted a complete
JPG file. If it's uncompressed RGB data then you'll have
extracted the RGB bytes, but in reverse order and without
a header. Maybe you could paint that directly to screen without
building a BMP file? Possibly. Maybe a JPG thumbnail can also
be loaded into a Picture by bytes rather than file path? I
seem to remember there was a way to do that. But either way,
you need to know about the EXIF storage system in order to
get it out.
GS
2020-03-29 17:30:48 UTC
Permalink
Post by Arne Saknussemm
It was Sat, 28 Mar 2020 14:43:48 -0400 when
Post by Mayayana
I maybe should have explained that: One can't
just extract a thumbnail and load it into a
picturebox. A JPG thumbnail is, in fact, an actual
file. But uncompressed RGB thumbnails are in reverse
byte order and have no header. So the bytes have
to be reversed. Then a header has to be created.
Only then do you have a file that can be loaded.
My point is that Windows GDI APIs work on DIBs, those
are an in-memory representation of an image which may
then be stored to (or retrieved from) whatever
format, be it JPG, PNG or whatever, such formats are
just STORAGE formats, so instead of focusing on how a
given image is stored, it would be a better idea to
focus on how to quickly render it, then, to retrieve
the image from storage and decode it, there are a
bunch of libraries and APIs, so that shouldn't be a
big issue, nor it would be how the image is stored,
once you load and decode it from storage, you'll have
a DIB and that's all you need to show/manipulate it,
no need to worry about orientation/format/whatever
The .NET examples I've found seem to do this because when they Save the
modified image the format is passed as arg2. Since VB6 doesn't work with the
.NET Framework (or does it somehow?) I'm looking to duplicate in VB6!
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
GS
2020-03-29 17:54:10 UTC
Permalink
Post by GS
Post by Arne Saknussemm
It was Sat, 28 Mar 2020 14:43:48 -0400 when
Post by Mayayana
I maybe should have explained that: One can't
just extract a thumbnail and load it into a
picturebox. A JPG thumbnail is, in fact, an actual
file. But uncompressed RGB thumbnails are in reverse
byte order and have no header. So the bytes have
to be reversed. Then a header has to be created.
Only then do you have a file that can be loaded.
My point is that Windows GDI APIs work on DIBs, those
are an in-memory representation of an image which may
then be stored to (or retrieved from) whatever
format, be it JPG, PNG or whatever, such formats are
just STORAGE formats, so instead of focusing on how a
given image is stored, it would be a better idea to
focus on how to quickly render it, then, to retrieve
the image from storage and decode it, there are a
bunch of libraries and APIs, so that shouldn't be a
big issue, nor it would be how the image is stored,
once you load and decode it from storage, you'll have
a DIB and that's all you need to show/manipulate it,
no need to worry about orientation/format/whatever
The .NET examples I've found seem to do this because when they Save the
modified image the format is passed as arg2. Since VB6 doesn't work with the
.NET Framework (or does it somehow?) I'm looking to duplicate in VB6!
So what I'm looking to do is this:

1. Loop thru a dir and grab each pic file to process;
Already got this working recursively!

Need way to do the following:
2. Determine orientation by examine w/h max to get new width;
This will be 480 if portrait, 640 if landscape.
Aspect ratio will auto-set height.

3. Save the pic file by overwriting existing;
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
Mayayana
2020-03-29 19:36:33 UTC
Permalink
"GS" <***@v.invalid> wrote

| Need way to do the following:
| 2. Determine orientation by examine w/h max to get new width;
| This will be 480 if portrait, 640 if landscape.
| Aspect ratio will auto-set height.
|
| 3. Save the pic file by overwriting existing;
|


Here's my image class:

https://www.jsware.net/Files2/imclass.zip

The code works like this:

Dim oPic As StdPicture
Dim ImOb As cImage, ImOb2 As cImage

Set oPic = LoadPicture(sPathSrc)
If (Err.Number = 0) Then
Set ImOb = New cImage
LRet = ImOb.CopyStdPicture(oPic)

'-------
sPathSrc is the path of the image file. So you
load a BMP/JPG/GIF into a StdPicture and then
copy that into the class. From there all sorts of
operations can be done, including resizing, cropping,
etc. and writing a new imahe to disk as BMP or JPG.
These were the most efficient methods I found.

There's also

https://www.jsware.net/Files2/resizetest.zip

That demonstrates that GDI+ resizing is faster than
VB methods using an Image control, with much
better picture quality. It's also slightly better
than WIA in terms of both speed and quality.

For sheer speed with large images I found jpegturbo
was the fastest resizer, by using the closest size
among the 8 (?) presets, then resizing that as needed.
Going from very big down to small is what takes so
much time.

Of course, none of this will handle PNG or TIF.
You'll need external libraries for that. I have code
for rendering PNG in VB, but not for saving as PNG.
And it's slow, anyway.
GS
2020-03-29 20:19:27 UTC
Permalink
Post by Mayayana
Post by GS
2. Determine orientation by examine w/h max to get new width;
This will be 480 if portrait, 640 if landscape.
Aspect ratio will auto-set height.
3. Save the pic file by overwriting existing;
https://www.jsware.net/Files2/imclass.zip
Dim oPic As StdPicture
Dim ImOb As cImage, ImOb2 As cImage
Set oPic = LoadPicture(sPathSrc)
If (Err.Number = 0) Then
Set ImOb = New cImage
LRet = ImOb.CopyStdPicture(oPic)
'-------
sPathSrc is the path of the image file. So you
load a BMP/JPG/GIF into a StdPicture and then
copy that into the class. From there all sorts of
operations can be done, including resizing, cropping,
etc. and writing a new imahe to disk as BMP or JPG.
These were the most efficient methods I found.
Looks simple enough but was looking to NOT need an image control. I'll give
this a try regardless.
Post by Mayayana
There's also
https://www.jsware.net/Files2/resizetest.zip
downloaded this earlier...
Post by Mayayana
That demonstrates that GDI+ resizing is faster than
VB methods using an Image control, with much
better picture quality. It's also slightly better
than WIA in terms of both speed and quality.
This might be better suited so I'll play with...
Post by Mayayana
For sheer speed with large images I found jpegturbo
was the fastest resizer, by using the closest size
among the 8 (?) presets, then resizing that as needed.
Going from very big down to small is what takes so
much time.
Give the shear volume of pics, speed is important for sure! Some of the files
are 6-7mb (jpg camera pics) and others are page scans (jpg); - a few are web
source (png) but I'll show her how to SaveAs JPG.
Post by Mayayana
Of course, none of this will handle PNG or TIF.
You'll need external libraries for that. I have code
for rendering PNG in VB, but not for saving as PNG.
And it's slow, anyway.
I'm using SnippingTool to save PNGs as JPGs; - doing this makes a much smaller
file, and there are very few in this format to begin with anyway!
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
Mayayana
2020-03-29 22:40:36 UTC
Permalink
"GS" <***@v.invalid> wrote

| > sPathSrc is the path of the image file. So you
| > load a BMP/JPG/GIF into a StdPicture and then
| > copy that into the class. From there all sorts of
| > operations can be done, including resizing, cropping,
| > etc. and writing a new imahe to disk as BMP or JPG.
| > These were the most efficient methods I found.
|
| Looks simple enough but was looking to NOT need an image control. I'll
give
| this a try regardless.

Not an image control. A class that provides an
image object to simplify operations. You load the
file into a StdPicture, then copy that to the image
*class*. Then you can resize, crop, write to disk
without further handling details.
GS
2020-03-29 22:49:09 UTC
Permalink
Post by Mayayana
Post by Mayayana
sPathSrc is the path of the image file. So you
load a BMP/JPG/GIF into a StdPicture and then
copy that into the class. From there all sorts of
operations can be done, including resizing, cropping,
etc. and writing a new imahe to disk as BMP or JPG.
These were the most efficient methods I found.
Looks simple enough but was looking to NOT need an image control. I'll give
this a try regardless.
Not an image control. A class that provides an
image object to simplify operations. You load the
file into a StdPicture, then copy that to the image
*class*. Then you can resize, crop, write to disk
without further handling details.
Nice! Thanks for clarifying as I know absolutely nothing about working with
images. (I use a 3rd party utility for making icons after I design them and
screencapture to transparent GIFs)
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
Mayayana
2020-03-30 03:17:47 UTC
Permalink
"GS" <***@v.invalid> wrote

| Nice! Thanks for clarifying as I know absolutely nothing about working
with
| images. (I use a 3rd party utility for making icons after I design them
and
| screencapture to transparent GIFs)
|

If you don't ffigure it out I can provide more sample
code. But it's pretty basic from outside the class.
You create an instance from a StdPicture and then
use the functions of the class object to do whatever
you need. Internally it's as lean as I could get it.
GS
2020-03-30 11:44:20 UTC
Permalink
Post by Mayayana
Nice! Thanks for clarifying as I know absolutely nothing about working with
images. (I use a 3rd party utility for making icons after I design them and
screencapture to transparent GIFs)
If you don't ffigure it out I can provide more sample
code. But it's pretty basic from outside the class.
You create an instance from a StdPicture and then
use the functions of the class object to do whatever
you need. Internally it's as lean as I could get it.
Thanks for making it as simple as possible; - still, it'll take awhile for me
to digest! At first read I don't see where AspectRatio plays a part; - looks
like I need to specify both width and height. This could be problematic where
original size is not 3x4 or 4x3 AR, requiring lots of calc code. (Unfortunately
most of the pics are NOT either AR) The apps I'm using now auto-adjust
according to AR; - I need to duplicate that behavior so I only pass 1 dimension
based on orientation derived from the original pic! I could be wrong though!
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
Mayayana
2020-03-30 13:52:30 UTC
Permalink
"GS" <***@v.invalid> wrote

| Thanks for making it as simple as possible; - still, it'll take awhile for
me
| to digest! At first read I don't see where AspectRatio plays a part; -
looks
| like I need to specify both width and height. This could be problematic
where
| original size is not 3x4 or 4x3 AR, requiring lots of calc code.
(Unfortunately
| most of the pics are NOT either AR) The apps I'm using now auto-adjust
| according to AR; - I need to duplicate that behavior so I only pass 1
dimension
| based on orientation derived from the original pic! I could be wrong
though!
|

Wouldn't that just be a calculation? I didn't
understand your original note about getting ratio,
but I assumed were reducing the largest dimension
to 640. So then it's just arithmetic to get the small
dim as the same ratio.
smalldim = (bigdim \ 640) x orig small dim

I haven't looked at this stuff for awhile. I'm
wondering whether the class is really the best
thing. Maybe if I have a chance I'll try a test,
adding the VB Bilinear resize method to the resize
test I linked from online.

Some time ago we spent a long time dealing
with this. I was looking for the fastest thumbnail
generator. I finally ended up with turbojpeg +
minor resizing.

The class I have was for my photo editing program.

I assume you want decent quality. The resize test
I linked is interesting in that respect. It shows that
GDI+ is slightl faster than WIA and much faster than
resizing an image control. But it also shows quality
differences. I have a 12 MB image of maple trees.
GDI+ resizes well but blurs it slightly. VB image control
produces far too much contract, making the leaves look
like bright color dots. WIA is slightly inferior to GDI+.
So GDI+ is best. I expect it's probably also better
than StretchBlt, but I don't know for sure.

What I also don't know is how the speed and quality
of GDI+ resize compare to the straight VB math code
for bilinear and bicubic in the cImage class. But maybe
I'll try to add that into the test project.
GS
2020-03-30 16:37:40 UTC
Permalink
Sorry if I wasn't clear! Here's my goal:

Loop a folder of pics and process each as follows...
'get existing dims of each pic;
picWidth = Pic.Width: picHeight = Pic.Height
'determine orientation by testing width to height dims;
IsPortrait = (picHeight > picWidth): IsSquare = (picHeight = picWidth)

'resize accordingly
If IsSquare Then Call ResizeS
If IsPortrait Then Call ResizeP Else Call ResizeL
End If

..where these Resize?() functions will test if the pic is larger than desired
before modifying.

Camera pics are normally 3:4 AR and so should be straight forward; - it's the
self-sized ones that I'm concerned about. In this case there is a filesize
limit as well since these are scans of magazine pages, so I'll need to do
downsizing by percent as well.
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
GS
2020-03-30 17:35:20 UTC
Permalink
I stumbled onto a post by Olaf stating RichClient5 has this capability built
into one of its DLLs. I'll look into that as well...
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
GS
2020-03-28 18:59:55 UTC
Permalink
As usual, a very thorough response! Big thanks for this info; - I will look
into all of it.

More about my task:
A friend's wife is a hoarder of pics, and snap-happy as well. Problem is that
now she has twice filled up the HDD in her laptop to the point of crashing. She
has absolutely 100s of 1000s of pics. I decided to introduce her to an external
storage device for all data, leaving the laptop HDD for OS+apps only. So far so
good! I replaced the original HDD with an equal size SSD and now recovering all
her pics from the old HDD onto a 3.5" x 7200RPM external drive (1TB for now).

I found this app...

https://www.bricelam.net/ImageResizer/

..which is working to my liking in that it allows selecting pics in WE and lets
me configure output sizes. (Resizes 300+ pics in less than 10 seconds) Problem
is that it makes some larger not smaller, even though there's an option setting
to not do that.

Since I already have a working files explorer app I thought I'd just add one
more custom feature that does same. I'm replacing existing files with smaller
versions suitable for Web use, (640x480) for both orientations
(portrait/landscape). So far, Office Picture Manager is doing the best job but
it requires hands-on selection of the specific files (their thumbnails) to
resize. Very slow so I'm looking to duplicate what/how that ImageResizer app
does.

I found stuff to convert BMPs to JPG, and lots of .NET solutions but I'm not
looking to add this feature to my C# version of the files explorer app. I
already have a recursive routine to drill down thru subfolders so just
need/want to pass the filename to be resized along with its new dims.
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
Mayayana
2020-03-28 20:39:58 UTC
Permalink
"GS" <***@v.invalid> wrote
|
| ..which is working to my liking in that it allows selecting pics in WE and
lets
| me configure output sizes. (Resizes 300+ pics in less than 10 seconds)
Problem
| is that it makes some larger not smaller, even though there's an option
setting
| to not do that.

Ah. I thought you wanted to do something like an
Explorer thumbnail view. You could take a look
at this:

https://www.jsware.net/jsware/pprep.php5

I made it mostly for the woman I live with but
also sold it as shareware for a few years. You drop
a file or folder, then you can batch process a whole
folder with resizing and/or cropping. To accommodate
a large audience there are only 3 possible sizes, but
in the settings you can decide what those are. The
cropping was especially aimed at easily creating images
with the right ratio for various printing options, to
fit an 8x10 frame, a 3x5 print, etc.

If it's useful I'm happy to share whatever code you
might want. I think most of it uses some very nice
code from one Peter Scale, who wrote various
image operations in pure VB, including various resizing
methods.
GS
2020-03-28 21:57:06 UTC
Permalink
Post by Mayayana
Post by GS
..which is working to my liking in that it allows selecting pics in WE and
lets me configure output sizes. (Resizes 300+ pics in less than 10 seconds)
Problem is that it makes some larger not smaller, even though there's an
option setting to not do that.
Ah. I thought you wanted to do something like an
Explorer thumbnail view. You could take a look
https://www.jsware.net/jsware/pprep.php5
I made it mostly for the woman I live with but
also sold it as shareware for a few years. You drop
a file or folder, then you can batch process a whole
folder with resizing and/or cropping. To accommodate
a large audience there are only 3 possible sizes, but
in the settings you can decide what those are. The
cropping was especially aimed at easily creating images
with the right ratio for various printing options, to
fit an 8x10 frame, a 3x5 print, etc.
If it's useful I'm happy to share whatever code you
might want. I think most of it uses some very nice
code from one Peter Scale, who wrote various
image operations in pure VB, including various resizing
methods.
Thank you!
I'll also look into this Peter Scale to see if any of his works are around...
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
GS
2020-03-28 22:44:30 UTC
Permalink
Post by Mayayana
Post by GS
..which is working to my liking in that it allows selecting pics in WE and
lets me configure output sizes. (Resizes 300+ pics in less than 10 seconds)
Problem is that it makes some larger not smaller, even though there's an
option setting to not do that.
Ah. I thought you wanted to do something like an
Explorer thumbnail view. You could take a look
https://www.jsware.net/jsware/pprep.php5
I made it mostly for the woman I live with but
also sold it as shareware for a few years. You drop
a file or folder, then you can batch process a whole
folder with resizing and/or cropping. To accommodate
a large audience there are only 3 possible sizes, but
in the settings you can decide what those are. The
cropping was especially aimed at easily creating images
with the right ratio for various printing options, to
fit an 8x10 frame, a 3x5 print, etc.
If it's useful I'm happy to share whatever code you
might want. I think most of it uses some very nice
code from one Peter Scale, who wrote various
image operations in pure VB, including various resizing
methods.
Found nothing on Peter Scale yet but I'm very interested in the resizing code
you use!
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
Mayayana
2020-03-29 02:49:51 UTC
Permalink
"GS" <***@v.invalid> wrote

| Found nothing on Peter Scale yet but I'm very interested in the resizing
code
| you use!
|
I think this is it:

http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=46515&lngWId=1

I'll try to pull together my code tomorrow and
post it or post a link.
GS
2020-03-29 17:22:38 UTC
Permalink
Post by Mayayana
Post by GS
Found nothing on Peter Scale yet but I'm very interested in the resizing
code you use!
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=46515&lngWId=1
Got it; - will have a look-see shortly! Thanks...
Post by Mayayana
I'll try to pull together my code tomorrow and
post it or post a link.
That would be great! Big thanks for your interest!
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
Peter T
2020-03-30 16:29:59 UTC
Permalink
Post by GS
Hi All,
I've been searching for ideas on how to manage batch resizing of images in
a VB6.exe explorer app,
I haven't been all through the thread so this might have already have been
suggested -

https://www.mvps.org/emorcillo/en/code/vb6/thumbnail.shtml

I adapted it a long time ago for VBA in Excel to create thumbnails of all
images in the supplied folder and show them on a form (in a column in a
scrollable frame), click a thumbnail to show the full size image on the same
form. For your purposes wouldn't need to show them, as StdPicture objects
just 'SavePicture' back to file, obviously with a modified name if to same
folder.

Peter T
GS
2020-03-30 16:34:42 UTC
Permalink
Post by Peter T
Post by GS
Hi All,
I've been searching for ideas on how to manage batch resizing of images in
a VB6.exe explorer app,
I haven't been all through the thread so this might have already have been
suggested -
https://www.mvps.org/emorcillo/en/code/vb6/thumbnail.shtml
I adapted it a long time ago for VBA in Excel to create thumbnails of all
images in the supplied folder and show them on a form (in a column in a
scrollable frame), click a thumbnail to show the full size image on the same
form. For your purposes wouldn't need to show them, as StdPicture objects
just 'SavePicture' back to file, obviously with a modified name if to same
folder.
Peter T
Thanks Peter, I'll look at this too. I'll be doing all my testing in Excel14
anyway since I already have a project going for doing other related tasks!
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
Peter T
2020-03-31 09:59:41 UTC
Permalink
Post by GS
Post by Peter T
Post by GS
Hi All,
I've been searching for ideas on how to manage batch resizing of images
in a VB6.exe explorer app,
I haven't been all through the thread so this might have already have
been suggested -
https://www.mvps.org/emorcillo/en/code/vb6/thumbnail.shtml
I adapted it a long time ago for VBA in Excel to create thumbnails of all
images in the supplied folder and show them on a form (in a column in a
scrollable frame), click a thumbnail to show the full size image on the
same form. For your purposes wouldn't need to show them, as StdPicture
objects just 'SavePicture' back to file, obviously with a modified name
if to same folder.
Peter T
Thanks Peter, I'll look at this too. I'll be doing all my testing in
Excel14 anyway since I already have a project going for doing other
related tasks!
I should have mentioned, if you just want the job done rather than the fun
of doing it yourself, look at www.irfanview.com

File / Batch Conversion/Rename / Advanced / Set long side to # (pixels, cm
or inches)
You'll probably want to tick preserve aspect ratio and resample, dozens more
options on the advanced page, save with same date/time as the original is a
nice touch.
Back on the main page various ways to filter which images to process, and an
'include subfolders' option.

I've been using IrfanView since last century and still find new things it
can do, my all time favourite freeware app since ever, bar none! Hmm, I'm
well overdue a top-up donation:)

Peter T
GS
2020-03-31 13:43:42 UTC
Permalink
Post by GS
Post by Peter T
Post by GS
Hi All,
I've been searching for ideas on how to manage batch resizing of images
in a VB6.exe explorer app,
I haven't been all through the thread so this might have already have been
suggested -
https://www.mvps.org/emorcillo/en/code/vb6/thumbnail.shtml
I adapted it a long time ago for VBA in Excel to create thumbnails of all
images in the supplied folder and show them on a form (in a column in a
scrollable frame), click a thumbnail to show the full size image on the
same form. For your purposes wouldn't need to show them, as StdPicture
objects just 'SavePicture' back to file, obviously with a modified name if
to same folder.
Peter T
Thanks Peter, I'll look at this too. I'll be doing all my testing in
Excel14 anyway since I already have a project going for doing other related
tasks!
I should have mentioned, if you just want the job done rather than the fun of
doing it yourself, look at www.irfanview.com
File / Batch Conversion/Rename / Advanced / Set long side to # (pixels, cm or
inches)
You'll probably want to tick preserve aspect ratio and resample, dozens more
options on the advanced page, save with same date/time as the original is a
nice touch.
Back on the main page various ways to filter which images to process, and an
'include subfolders' option.
I've been using IrfanView since last century and still find new things it can
do, my all time favourite freeware app since ever, bar none! Hmm, I'm well
overdue a top-up donation:)
Peter T
I have it and so will play; - thank you very much!
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
GS
2020-03-31 16:53:20 UTC
Permalink
Post by GS
Post by Peter T
Post by GS
Hi All,
I've been searching for ideas on how to manage batch resizing of images
in a VB6.exe explorer app,
I haven't been all through the thread so this might have already have been
suggested -
https://www.mvps.org/emorcillo/en/code/vb6/thumbnail.shtml
I adapted it a long time ago for VBA in Excel to create thumbnails of all
images in the supplied folder and show them on a form (in a column in a
scrollable frame), click a thumbnail to show the full size image on the
same form. For your purposes wouldn't need to show them, as StdPicture
objects just 'SavePicture' back to file, obviously with a modified name if
to same folder.
Peter T
Thanks Peter, I'll look at this too. I'll be doing all my testing in
Excel14 anyway since I already have a project going for doing other related
tasks!
I should have mentioned, if you just want the job done rather than the fun of
doing it yourself, look at www.irfanview.com
File / Batch Conversion/Rename / Advanced / Set long side to # (pixels, cm or
inches)
You'll probably want to tick preserve aspect ratio and resample, dozens more
options on the advanced page, save with same date/time as the original is a
nice touch.
Back on the main page various ways to filter which images to process, and an
'include subfolders' option.
I've been using IrfanView since last century and still find new things it can
do, my all time favourite freeware app since ever, bar none! Hmm, I'm well
overdue a top-up donation:)
Peter T
BINGO! Big thanks, Peter!
Don't know why I didn't do this already; - probably because I really don't use
it much as I do MSO PictureManager.
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
Mayayana
2020-03-30 22:20:37 UTC
Permalink
Got to playing with different methods of resizing.
Hands down winner: GDI+ bicubic. Below is what you need. I'm afraid
it's in bits. One function opens a file and loads it, resizes, then
paints the bitmap. If you take the loading path and combine it
with the saving part from the second half of the second function,
you'll have a load, resize, save as JPG that's better than other
options. If you use bicubic (4 as interpolation mode) then you
get a beter image than bilinear in about the same time.


Public Enum gdiplusStatus '-- returned by gdip* methods
Ok = 0
GenericError = 1
InvalidParameter = 2
OutOfMemory = 3
ObjectBusy = 4
InsufficientBuffer = 5
NotImplemented = 6
Win32Error = 7
WrongState = 8
Aborted = 9
FileNotFound = 10
ValueOverflow = 11
AccessDenied = 12
UnknownImageFormat = 13
FontFamilyNotFound = 14
FontStyleNotFound = 15
NotTrueTypeFont = 16
UnsupportedGdiplusVersion = 17
GdiplusNotInitialized = 18
PropertyNotFound = 19
PropertyNotSupported = 20
ProfileNotFound = 21
End Enum

Private Type GdiplusStartupInput
GdiplusVersion As Long
DebugEventCallback As Long
SuppressBackgroundThread As Long
SuppressExternalCodecs As Long
End Type

Private Type RECTF
nLeft As Single
nTop As Single
nWidth As Single
nHeight As Single
End Type

Public Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(0 To 7) As Byte
End Type

Private Const UnitPixel As Long = 2

Public Enum InterpolationConstants
InterpolationModeDefault = 0
InterpolationModeLowQuality = 1
InterpolationModeHighQuality = 2
InterpolationModeBilinear = 3
InterpolationModeBicubic = 4
InterpolationModeNearestNeighbor = 5
InterpolationModeHighQualityBilinear = 6
InterpolationModeHighQualityBicubic = 7
End Enum

Private Declare Function GdiplusStartup Lib "GdiPlus" (token As Long,
inputbuf As GdiplusStartupInput, Optional ByVal outputbuf As Long = 0) As
Long
Private Declare Function GdipLoadImageFromFile Lib "GdiPlus.dll" (ByVal
mFilename As Long, ByRef mImage As Long) As Long
Private Declare Function GdipDeleteGraphics Lib "GdiPlus.dll" (ByVal
mGraphics As Long) As Long
Private Declare Function GdipCreateFromHDC Lib "GdiPlus" (ByVal hdc As Long,
hGraphics As Long) As Long
Private Declare Function GdipDisposeImage Lib "GdiPlus" (ByVal Image As
Long) As Long
Private Declare Sub GdiplusShutdown Lib "GdiPlus" (ByVal token As Long)
Private Declare Function GdipCreateBitmapFromHBITMAP Lib "GdiPlus.dll"
(ByVal hbm As Long, ByVal hPal As Long, ByRef pBitmap As Long) As Long
Private Declare Function GdipGetImageBounds Lib "GdiPlus.dll" (ByVal nImage
As Long, srcRect As RECTF, srcUnit As Long) As Long
Private Declare Function GdipSetInterpolationMode Lib "GdiPlus" (ByVal
hGraphics As Long, ByVal Interpolation As Long) As Long
Private Declare Function GdipDrawImageRectRectI Lib "GdiPlus" (ByVal
hGraphics As Long, ByVal hImage As Long _
, ByVal dstX As Long, ByVal dstY As Long, ByVal
dstWidth As Long, ByVal dstHeight As Long _
, ByVal SrcX As Long, ByVal SrcY As Long, ByVal
srcWidth As Long, ByVal srcHeight As Long _
, ByVal srcUnit As Long, Optional ByVal
imageAttributes As Long = 0 _
, Optional ByVal Callback As Long = 0, Optional
ByVal callbackData As Long = 0) As Long
Public Declare Function GdipSaveImageToFile Lib "GdiPlus" (ByVal Image As
Long, ByVal sFilePath As Long, clsidEncoder As GUID, encoderParams As Any)
As Long

'-- used with GDIP:
Public Declare Function CLSIDFromString Lib "ole32" (ByVal str As Long, id
As GUID) As Long



'--resize an image in proportion to original and paint.
Public Function ResizeAndPaintGDIP(FileName As String, DesthDC As Long,
DestW As Long, Interpolation As Long) As Long
Dim GDIsi As GdiplusStartupInput
Dim gToken As Long, hGraphics As Long, hBitmap As Long, LRet As Long
Dim ImRect As RECTF
Dim DestH As Long
On Error Resume Next
GDIsi.GdiplusVersion = 1&
LRet = GdiplusStartup(gToken, GDIsi)
If LRet <> 0 Then ResizeAndPaintGDIP = LRet: Exit Function

LRet = GdipCreateFromHDC(DesthDC, hGraphics)
If hGraphics <> 0 Then
LRet = GdipLoadImageFromFile(StrPtr(FileName), hBitmap)
If hBitmap <> 0 Then
LRet = GdipGetImageBounds(hBitmap, ImRect, UnitPixel)
LRet = GdipSetInterpolationMode(hGraphics, Interpolation)
DestH = CLng(ImRect.nHeight * (DestW / ImRect.nWidth))
LRet = GdipDrawImageRectRectI(hGraphics, hBitmap, 0, 0, DestW,
DestH, 0, 0, ImRect.nWidth, ImRect.nHeight, UnitPixel, 0&, 0&, 0&)
GdipDisposeImage hBitmap
ResizeAndPaintGDIP = LRet
End If
GdipDeleteGraphics hGraphics
End If
GdiplusShutdown gToken
End Function


Public Function WriteJPG(sPath As String, ByVal Quality As Long) As Long
'11-11
Dim hdc As Long, LRet As Long, LRet2 As Long
Dim hGDIPBitmap As Long 'handle to GDI+ bitmap.
Dim BBits() As Byte
Dim GUIDEncodeJPG As GUID
Dim EncodeParams As EncoderParameters
Const EncoderValueType As Long = &H4
On Error Resume Next

ReDim BBits(BMPInfo.bmiHeader.biHeight * BytesPerScanLine) As Byte
hdc = CreateCompatibleDC(0&)
LRet = GetDIBits(hdc, CurPic, 0, Abs(BMPInfo.bmiHeader.biHeight),
BBits(0), BMPInfo, DIB_RGB_COLORS)
LRet2 = DeleteDC(hdc)
If (LRet = 0) Then
WriteJPG = 1
Exit Function
End If
GdipCreateBitmapFromGdiDib BMPInfo, ByVal VarPtr(BBits(0)), hGDIPBitmap
If hGDIPBitmap <> 0 Then
CLSIDFromString StrPtr("{557CF401-1A04-11D3-9A73-0000F81EF32E}"),
GUIDEncodeJPG
' Initialize the encoder parameters
EncodeParams.Count = 1
With EncodeParams.Parameter ' Quality
CLSIDFromString
StrPtr("{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"), .GUID
.NumberOfValues = 1
.Type = EncoderValueType
.Value = VarPtr(Quality)
End With
LRet = GdipSaveImageToFile(hGDIPBitmap, StrPtr(sPath),
GUIDEncodeJPG, EncodeParams)
GdipDisposeImage hGDIPBitmap ' Destroy the bitmap
Else
LRet = 2 'set error code.
End If

WriteJPG = LRet
End Function
GS
2020-03-30 22:50:20 UTC
Permalink
Wow! I really appreciate your commitment to this!

I'll need time to figure out what it's doing before I can start using it,
though, since it's all 'Greek' to me. Not to mention so many variations of
how-to with GDI+!

"If you use bicubic (4 as interpolation mode) then you get a beter image than
bilinear in about the same time."

Does this mean I should also pass 7 for the Quality arg of WriteJPG?
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
GS
2020-03-30 22:56:40 UTC
Permalink
Post by Mayayana
'--resize an image in proportion to original and paint.
Public Function ResizeAndPaintGDIP(FileName As String, DesthDC As Long,
DestW As Long, Interpolation As Long) As Long
Do I assume that DesthDC and DestW are my target sizes? How would I know this
prior to loading the image to find out existing size? (file details, perhaps?)
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
Mayayana
2020-03-31 01:24:32 UTC
Permalink
"GS" <***@v.invalid> wrote

|> '--resize an image in proportion to original and paint.
| > Public Function ResizeAndPaintGDIP(FileName As String, DesthDC As Long,
| > DestW As Long, Interpolation As Long) As Long
|
| Do I assume that DesthDC and DestW are my target sizes? How would I know
this
| prior to loading the image to find out existing size? (file details,
perhaps?)
|
No. DesthDC is destination DC. That's the handle
for painting, which you don't want. Maybe I can clean this
up, but I was doing it last minute today. (Now that I'm
home all day I don't seem to have a minute to spare!)

It's confusing because I had two functions. One is
opening a file and doing a resized paint to a picturebox.
The other is taking bitmap bits, getting an hBitmap
handle from that, and using the handle to save a JPG
to disk.
So a lot of what you want is here but the middle step,
resizing and ending up with an hBitmap, needs to be
done differently. I'll try to work on it tomorrow.
GS
2020-03-31 01:30:26 UTC
Permalink
Post by Mayayana
Post by GS
Post by Mayayana
'--resize an image in proportion to original and paint.
Public Function ResizeAndPaintGDIP(FileName As String, DesthDC As Long,
DestW As Long, Interpolation As Long) As Long
Do I assume that DesthDC and DestW are my target sizes? How would I know
this prior to loading the image to find out existing size? (file details,
perhaps?)
No. DesthDC is destination DC. That's the handle
for painting, which you don't want. Maybe I can clean this
up, but I was doing it last minute today. (Now that I'm
home all day I don't seem to have a minute to spare!)
It's confusing because I had two functions. One is
opening a file and doing a resized paint to a picturebox.
The other is taking bitmap bits, getting an hBitmap
handle from that, and using the handle to save a JPG
to disk.
So a lot of what you want is here but the middle step,
resizing and ending up with an hBitmap, needs to be
done differently. I'll try to work on it tomorrow.
Big thanks; - much appreciated!

I'm working out getting file info via "Shell.Application"; - going well!
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
Mayayana
2020-03-31 02:01:38 UTC
Permalink
"GS" <***@v.invalid> wrote

| I'm working out getting file info via "Shell.Application"; - going well!
|

That happens to be another area of interest for me.
I might have something useful from my explorer bar code.
GS
2020-03-31 02:11:58 UTC
Permalink
Post by Mayayana
Post by GS
I'm working out getting file info via "Shell.Application"; - going well!
That happens to be another area of interest for me.
I might have something useful from my explorer bar code.
I have this part working well from another project that retrieves extended file
properties via GetDetailsOf().
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
Mayayana
2020-03-31 21:41:02 UTC
Permalink
Garry,

I spent most of the day fiddling with this, trying to
paste together old code without it taking a lot of
time. I just didn't want to get into mixing GDI and
GDI+ to make it work.

But here's another solution I came up with in a few
minutes. It's a button sub from a test program.
You need a reference to Windows Image Acquisition 2.
(It may need to be installed on XP. I don't remember.)
Then you need the button, a text box maned TTime,
and the declare. It will process a 10 MB JPG in about
1/3 second. In my other tests of painting an image it
wasn't quite as nice or quite as fast as GDI+, but it's
not far behind.

It might need a little work. One image kept erroring with
"the parameter is incorrect" on the ImProc.Apply line.
I don't know why. Others worked fine. A 12 MB image took
344 ms to load, resize, and save as a new file. Yet Irfan
View said it took 297 ms just to load the image. So I guess
344 isn't bad.

'------------------------------------------------

Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Tick1 As Long, Tick2 As Long

Private Sub ButWIA2_Click()
Dim s1 As String
Dim W As Long, H As Long
Dim DestH As Long, DestW As Long, SrcW As Long, SrcH As Long, LSize As Long
Dim Img1 As ImageFile, Img2 As ImageFile
Dim ImProc As ImageProcess
TTime.Text = ""
Tick1 = GetTickCount
Set Img1 = New ImageFile
Set ImProc = New ImageProcess
Img1.LoadFile TPath.Text
LSize = 640
SrcW = Img1.Width
SrcH = Img1.Height
Debug.Print SrcW & " " & SrcH
If SrcW >= SrcH Then
DestW = LSize
DestH = SrcH * (DestW / SrcW)
Else
DestH = LSize
DestW = SrcW * (DestH / SrcH)
End If


While (ImProc.Filters.Count > 0)
ImProc.Filters.Remove 1
Wend
ImProc.Filters.Add ImProc.FilterInfos("Scale").FilterID
ImProc.Filters(1).Properties("MaximumWidth") = DestW
ImProc.Filters(1).Properties("MaximumHeight") = DestH
ImProc.Filters(1).Properties("PreserveAspectRatio") = True
Set Img1 = ImProc.Apply(Img1)

Dim s As String, Pt1 As Long
s = TPath.Text
Pt1 = InStrRev(s, ".")
s = Left$(s, (Pt1 - 1)) & "640.jpg"
Img1.SaveFile s

Set ImProc = Nothing
Set Img1 = Nothing

Tick2 = GetTickCount
TTime.Text = CStr(Tick2 - Tick1)

End Sub
GS
2020-03-31 21:51:57 UTC
Permalink
Thank you so much for your time&effort; - I appreciate it immensely!

Irfanview seems to be doing a much better job 'all-in-1-app' than anything I've
tried so far. (800+ files in about 8 seconds)

I'll spend time with your solution (once I've gained some lost ground here) so
I can have my own custom feature[s].
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
Mayayana
2020-04-01 01:08:39 UTC
Permalink
"GS" <***@v.invalid> wrote

| Thank you so much for your time&effort; - I appreciate it immensely!
|
| Irfanview seems to be doing a much better job 'all-in-1-app' than anything
I've
| tried so far. (800+ files in about 8 seconds)
|
| I'll spend time with your solution (once I've gained some lost ground
here) so
| I can have my own custom feature[s].
|

OK. I'll leave it at that. You probably can't beat
Irfan View. It was nice to refresh my memory a bit,
though. I've got free time lately but haven't had
any interesting coding projects for awhile.
GS
2020-04-01 01:14:37 UTC
Permalink
Post by Mayayana
Post by GS
Thank you so much for your time&effort; - I appreciate it immensely!
Irfanview seems to be doing a much better job 'all-in-1-app' than anything
I've tried so far. (800+ files in about 8 seconds)
I'll spend time with your solution (once I've gained some lost ground here)
so I can have my own custom feature[s].
OK. I'll leave it at that. You probably can't beat
Irfan View. It was nice to refresh my memory a bit,
though. I've got free time lately but haven't had
any interesting coding projects for awhile.
Ah, and I have the interest but no time lately!
--
Garry

Free usenet access at http://www.eternal-september.org
Classic VB Users Regroup!
comp.lang.basic.visual.misc
microsoft.public.vb.general.discussion
Loading...