Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Resize all images in TImageList



Permlink Replies: 10 - Last Post: Mar 30, 2015 8:54 PM Last Post By: Albert Wiersch
Albert Wiersch

Posts: 35
Registered: 10/2/04
Resize all images in TImageList
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 27, 2015 7:59 AM
I'm having a lot of trouble figuring out how to resize all the images in
a TImageList.

I tried going through each image in the image list and grabbing it with
GetBitmap(i,src), then drawing it on another TBitmap with
dest->Canvas->StretchDraw(R,src), then adding it to another TImageList
with Add(dest,NULL).

This somewhat works but the images are still messed up... perhaps a
pixel format or transparency issue?

What is the proper way? I would have hoped this would be a simple
operation but it appears not.

--
Thanks,
Albert Wiersch
https://www.htmlvalidator.com/
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Resize all images in TImageList
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 27, 2015 10:13 AM   in response to: Albert Wiersch in response to: Albert Wiersch
Albert wrote:

This somewhat works but the images are still messed up...

In what way exactly?

What is the proper way?

What you are already doing is pretty much the only way to do it.

--
Remy Lebeau (TeamB)
Albert Wiersch

Posts: 35
Registered: 10/2/04
Re: Resize all images in TImageList
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 30, 2015 12:13 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
On 3/27/2015 12:13 PM, Remy Lebeau (TeamB) wrote:
Albert wrote:

This somewhat works but the images are still messed up...

In what way exactly?

I replied but I'm not sure it went through... it's been rather difficult
accessing these newsgroups lately. Server problems?

If my reply doesn't show up soon then I'll re-send it.

--
Thanks,
Albert Wiersch
https://www.htmlvalidator.com/
Albert Wiersch

Posts: 35
Registered: 10/2/04
Re: Resize all images in TImageList
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 30, 2015 12:14 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
On 3/27/2015 12:13 PM, Remy Lebeau (TeamB) wrote:
Albert wrote:

This somewhat works but the images are still messed up...

In what way exactly?

Trying my reply again:

Hello Remy,

Before resizing:
https://www.htmlvalidator.com/png/resizebug/before.png

After resizing (doubling):
https://www.htmlvalidator.com/png/resizebug/after.png

As you can see the resized images are 'messed up' but I don't know why.

My code below:
void AWDPI_Scale_TImageList(TImageList *images) {
const int width(2*images->Width), height(2*images->Height);
TRect R(0,0,width,height);

TImageList *newimages(new TImageList(NULL));
newimages->Height=height;
newimages->Width=width;

TBitmap *dest(new TBitmap);
dest->Height=height;
dest->Width=width;

TBitmap *src(new TBitmap);
src->PixelFormat=pf32bit;

const size_t numimages(images->Count);
for (size_t i(0);i<numimages;i++) {
images->GetBitmap(i,src);
dest->Canvas->StretchDraw(R,src);
newimages->Add(dest,NULL);
}

images->Assign(newimages);
delete dest;
delete src;
delete newimages;
}
//---------------------------------------------------------------------------

Any ideas? Thanks.

--
Thanks,
Albert Wiersch
https://www.htmlvalidator.com/
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Resize all images in TImageList
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 30, 2015 12:56 PM   in response to: Albert Wiersch in response to: Albert Wiersch
Albert wrote:

As you can see the resized images are 'messed up' but I don't
know why.

Your images are overlapping because you are not resetting the intermediate
TBitmap objects on each loop iteration. You are drawing new images on top
of old images. TImageList::GetBitmap() and TBitmap::StretchDraw() do not
erase a TBitmap, they simply draw on top of whatever is already on the TBitmap.
So your loop need to either:

1) destroy+recreate the TBitmap objects on each iteration:

void AWDPI_Scale_TImageList(TImageList *images)
{
    const int width(2*images->Width), height(2*images->Height);
    TRect R(0,0,width,height);
 
    TImageList *newimages(new TImageList(NULL));
    newimages->Height=height;
    newimages->Width=width;
 
    const size_t numimages(images->Count);
    for (size_t i(0); i < numimages; ++i)
    {
        TBitmap *src(new TBitmap);
        src->PixelFormat=pf32bit;
        images->GetBitmap(i,src);
 
        TBitmap *dest(new TBitmap);
        dest->Height=height;
        dest->Width=width;
        dest->Canvas->StretchDraw(R,src);
        newimages->Add(dest,NULL);
        delete dest;
 
        delete src;
    }
 
    images->Assign(newimages);
    delete newimages;
}

2) resize the TBitmaps to 0x0 dimensions to clear them, then resize them
back to the proper size when drawing:

void AWDPI_Scale_TImageList(TImageList *images)
{
    const int width(2*images->Width), height(2*images->Height);
    TRect R(0,0,width,height);
 
    TImageList *newimages(new TImageList(NULL));
    newimages->Height=height;
    newimages->Width=width;
 
    TBitmap *dest(new TBitmap);
 
    TBitmap *src(new TBitmap);
    src->PixelFormat=pf32bit;
 
    const size_t numimages(images->Count);
    for (size_t i(0); i < numimages; ++i)
    {
        src->Height=0;
        src->Width=0;
 
        dest->Height=0;
        dest->Width=0;
 
        images->GetBitmap(i,src);
 
        dest->Height=height;
        dest->Width=width;
        dest->Canvas->StretchDraw(R,src);
 
        newimages->Add(dest,NULL);
 
    }
 
    images->Assign(newimages);
 
    delete src;
    delete dest;
    delete newimages;
}

3) draw a background to erase the TBitmap objects without having to resize
them:

void AWDPI_Scale_TImageList(TImageList *images)
{
    const int srcWidth(images->Width), srcHeight(images->Height);
    const int dstWidth(2*srcWidth), dstHeight(2*srcHeight);
    TRect srcR(0,0,srcWidth,srcHeight);
    TRect dstR(0,0,dstWidth,dstHeight);
 
    TImageList *newimages(new TImageList(NULL));
    newimages->Height=dstHeight;
    newimages->Width=dstWidth;
 
    TBitmap *dest(new TBitmap);
    dest->Height=dstHeight;
    dest->Width=dstWidth;
 
    TBitmap *src(new TBitmap);
    src->PixelFormat=pf32bit;
 
    const size_t numimages(images->Count);
    for (size_t i(0); i < numimages; ++i)
    {
        images->GetBitmap(i,src);
 
        dest->Canvas->StretchDraw(dstR,src);
        newimages->Add(dest,NULL);
 
        src->Canvas->Brush->Color = ...;
        src->Canvas->FillRect(srcR);
 
        dest->Canvas->Brush->Color = ...;
        dest->Canvas->FillRect(dstR);
    }
 
    images->Assign(newimages);
 
    delete src;
    delete dest;
    delete newimages;
}


--
Remy Lebeau (TeamB)
Albert Wiersch

Posts: 35
Registered: 10/2/04
Re: Resize all images in TImageList
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 30, 2015 1:54 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
On 3/30/2015 2:56 PM, Remy Lebeau (TeamB) wrote:

Your images are overlapping because you are not resetting the intermediate
TBitmap objects on each loop iteration.

Thanks!

It seems to be working. Now I can try to do what I was originally
wanting to do to make my app look better on high DPI screens. :)

--
Thanks,
Albert Wiersch
https://www.htmlvalidator.com/
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Resize all images in TImageList
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 30, 2015 2:30 PM   in response to: Albert Wiersch in response to: Albert Wiersch
Albert wrote:

It seems to be working. Now I can try to do what I was originally
wanting to do to make my app look better on high DPI screens. :)

Scaling images upward is not the best choice for that. You should start
with larger images and scale them down instead. A better solution is to
simply use different images for different resolutions, then you can use higher-resolution
images for higher DPIs and lower-resolution images for lower DPIs. Scaling
alone usually produces unwanted artifacts in images, so use DPI-appropriate
images instead.

--
Remy Lebeau (TeamB)
Albert Wiersch

Posts: 35
Registered: 10/2/04
Re: Resize all images in TImageList
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 30, 2015 8:54 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
On 3/30/2015 4:30 PM, Remy Lebeau (TeamB) wrote:
Albert wrote:

Scaling images upward is not the best choice for that. You should start
with larger images and scale them down instead. A better solution is to
simply use different images for different resolutions, then you can use higher-resolution
images for higher DPIs and lower-resolution images for lower DPIs. Scaling
alone usually produces unwanted artifacts in images, so use DPI-appropriate
images instead.

Yes, I would scale down in the actual application. I have added a set of
32x32 icons and am using those for higher DPIs instead of the original
16x16 set.

I'm not sure if I am going to scale at all though. It seems to be good
enough if I just switch from the 16x16 icons to the 32x32 set of icons
at a certain DPI (like 175% and higher)... but if I can find a way to
scale that looks good then I may use that method to scale the 32x32
icons. I'm still investigating but I feel like I've already put in
enough time for the benefit that all this 'DPI work' will bring. :)

--
Thanks,
Albert Wiersch
https://www.htmlvalidator.com/
Albert Wiersch

Posts: 35
Registered: 10/2/04
Re: Resize all images in TImageList
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 30, 2015 2:23 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
On 3/30/2015 2:56 PM, Remy Lebeau (TeamB) wrote:

Your images are overlapping because you are not resetting the intermediate
TBitmap objects on each loop iteration.

Now, next question... is there an easy way to choose a better built-in
resizing algorithm or do I have to go out on the net and try to find
some resizing code? I'm using XE6.

Any suggestions?

--
Thanks,
Albert Wiersch
https://www.htmlvalidator.com/
Quentin Correll


Posts: 2,412
Registered: 12/1/99
Re: Resize all images in TImageList
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 27, 2015 11:04 AM   in response to: Albert Wiersch in response to: Albert Wiersch
Albert,

| This somewhat works but the images are still messed up..

What do you mean by "messed up"?

--

Q -- XanaNews 1.19.1.372 - 2015-03-27 11:04:12
Peter Below

Posts: 1,227
Registered: 12/16/99
Re: Resize all images in TImageList
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 27, 2015 12:17 PM   in response to: Albert Wiersch in response to: Albert Wiersch
Albert Wiersch wrote:

I'm having a lot of trouble figuring out how to resize all the images
in a TImageList.

I tried going through each image in the image list and grabbing it
with GetBitmap(i,src), then drawing it on another TBitmap with
dest->Canvas->StretchDraw(R,src), then adding it to another
TImageList with Add(dest,NULL).

This somewhat works but the images are still messed up... perhaps a
pixel format or transparency issue?

What do you expect? A bitmap is made of a fixed size of pixels, and if
you want to size it larger more pixels have to be created from the
existing ones in some manner. If you resize by factor 2, for instance,
every pixel in the original image would give four pixels in the
resulting image. The result depends on the algorithm used to calculate
the color values for the new pixels, and Windows is not that smart
about that.


--
Peter Below (TeamB)

Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02