reuse resource image bitmap instead of duplicate them in xfm files - delphi

I have several TBitBtns in several different forms of a Delphi 7 CLX application that make use of some images as Glyph (TBitMap), now the problem is that though the images are the same, each time I load the TBitMap as Glyph property of the TBitButton(from the designer tool) the image is loaded on the form xfm file and the size of the final executable bloat ...
Since I use the same image for different buttons in different forms, what's the best way to share the image ? A resource file ?
How can I avoid to bloat the final executable size ?

I'd recommend adding a DataModule into the project. At the DataModule, you can create an TImageList and fill it with images. Most visual components allow loading glyphs from ImageLists, and you can easily specify a glyph from DataModule's ImageList in design-time.

Related

How to add design time icon for FireMonkey component?

I have read this article by Paweł Głowacki and I have been able to display an icon for my component. The result is the following:
I can see the image in the Tool Palette and in the structure view. By the way in the designer I see the default icon:
How can I display the icon of my component in the designer as well?
I am using Delphi Tokyo 10.2 Update 2. I have followed the article I have linked to get the image shown. My component is the following:
type
TEquationSolver = class(TComponent)
//code...
end;
Basically, I have done the following:
I have created 3 bitmaps (16x16 24x24 32x32) and a png (128x128)
I have added them as resources going into Project > Resources and Images
I have called them TEquationSolver with the suffix that indicates the size. In this way they are properly displayed on the IDE.
What am I missing for the design time part? In this article I have read the following:
Our guide is: Use PNG if you want very easy backwards compatibility,
or small file (BPL) size; use bitmaps if you want fast loading. We
use bitmaps for 16, 24, and 32px icons, and PNG for the 128px icons.
In fact I have 16x16, 24x24, 32x32 bitmaps and the 128px png. Is there something else?
It seems that you have to create the files I have shown above plus the image for the Designer. The latter needs to match the name of the class that inherits from TComponent (in my case):
As you can see I have added another bitmap (it's the 32x32, I have just made a copy and changed the name) and I have used TEquationSolver as name. After a Build + Install I have the following result:
Note that I could have added only logo.bmp as resource (with the ID that matches the TComponent-derived class name) and it would have worked anyway. The problem is that the pictures won't be neat because they'll be resized and they may appear blurred, like in my case.
For this reason I think that it's good:
Put an image that will appear in the form designer
Put the 16x16, 24x24, 32x32 and 128x128 that will be used by the IDE
The difference is evident in my case. When I have only a single bitmap the quality of the image is low but when I provide the various sizes they look better.

How can I keep the size of a Delphi application small when it has many TImage components?

I want to make an application using Delphi. The problem is I am going to have a lot of TImage components in it - which will make the exe size extremely large. So far my exe is 20MB large and I have only completed the home page, by my calculations the exe alone will be more than 10GB in size - which is way too much.
How can I make an app with hundreds/thousands of images and yet let the exe be small in size?
Don't put the images in the executable. Keep them in external files and load them at runtime.
This will require you to stop loading the images into the TImage controls at design-time and instead use dynamic code to load the image, and transfer to the TImage control. There are many advantages of doing so:
You keep your executable down to a reasonable size, one that can fit in the virtual address space.
You can use the most appropriate compression format for the images. If I recall correctly, a Delphi TImage will persists to a .dfm file in a very inefficient way. You can choose to use PNG or JPEG compression.
Keeping the files external allows you to better managed them when developing. You can keep them as separate files in your revision control system. Storing images in .dfm files makes for painstaking updates when you need to change the images. You have to do lots of interaction with the IDE. Storing as files allows you to overwrite the file, and commit to the repository.
If you don't need to keep your images in their original size, you can read them in at program startup and scale them to their "working" size. This will reduce your memory requirements immensely - for example, reducing an image to half its original width and height reduces memory requirements to a quarter of the original image.
If the images don't change, you can do this offline in a separate build process and reduce the load time a lot too. Otherwise, you can cache the reduced images during the load process to speed it up the next time the program is started.
You might find the binary code includes all the images as PNG file format, so it will be compile extremely application size for you.
I use the images in runtime, as JPG, so in the form's OnCreate events you can load from the Package.
Use the "Project" Menu "Deployment" to include your JPG files to the APK.
You can read more here:
http://blogs.embarcadero.com/davidi/2013/11/23/43005/

Rescale AnimatedGIF at run-time according to Windows DPI Display Settings?

In Delphi XE2, I have a JvGIFAnimator component (from JVCL) on a form. Now, when I run this program on a computer where the Windows DPI Display Settings are set to 125%, while all other GUI elements and system text are scaled up to 125%, the GIF animation unfortunately is not resized. The GIF is embedded in the JvGIFAnimator component with the TJvGIFAnimator.Image property at design time as a TJvGIFImage.
Is there a way to rescale the embedded GIF at run-time according to the Windows DPI Display Settings?
You'll have to do this yourself one way or another. There is nothing built in that will automatically rescale. Options include:
Decode each frame of the GIF. Use a graphics library to resize the images. Create a new GIF with the resized images.
Provide multiple GIFs at different sizes and use the one with size closest to the target.
Of these options, the latter is better. Resizing on the fly will lead to horrid visual artifacts and aliasing. Your animation will look dreadful. Not to mention all the coding involved. Choose option 2.
In fact, this issue is no different for rasterized animations as it is for rasterized static images. Just as you need to provide multiple glyphs for toolbar buttons, you need to supply multiple versions of your rasterized animations.

Clipping a filmstrip in png format (Delphi 2010)

I have a filmstrip of images in png format like this:
I'd like to know how to clip each of the images and put these images in a TImageList control, always preserving the transparency.
[EDIT]
Yes, at designtime the trick mentioned by RRUZ works fine, but I wanted to clip the images at runtime, i.e. by loading the filmstrip from resource or file
You must follow these steps:
set ColorDepth property to cd32Bit,
DrawingStyle to dsTransparent,
Height= 48,
Width=48,
then load the image and the result will be
Just import into the imagelist. It'll complain that it's too big and offer to break it into pieces for you. Works fine for me on D2005.
Another cool tip: I use AWIcons Pro http://www.awicons.com/icon-editor/ to edit icons (nice editor!). It has a feature that can export an icon as an imagelist (.bmp or .png format), thus making the filmstrip out of an icon. This makes it really handy to edit these things in .ico format, with a series of cells all the same size and depth, with each cell varying slightly. Then you export as an imagelist (I use .png) and then Delphi can break them back out into individual cells. Very slick. AWIcons isn't free, but features like this really make it productive.
At runtime, you would have to call TImageList.FileLoad. Except it won't work.
This in turn calls ImageList_LoadImage, with uFlags parameter value including the bit LR_LOADFROMFILE, which causes Windows to load from a file on disk. This underlying functionality only supports TBitmap (BMP) format.
See the nearly-duplicate question. PNG support is a designtime feature that is converting the PNG data into an internal non-PNG and not-exactly-a-BMP-either format, used internally by MS Common Controls library. View your DFM as text, and you will see what your PNG inputs have been turned into. The other answers show you that transparency is preserved, using bitmap-color based transparency.
If you want to keep your data in PNG format, you shouldn't be using a VCL TImageList to store it, because you're going to have to do a conversion from PNG to TBitmap to actually use TImageList.

TImage losing loaded picture

Running Turbo Delphi Pro.
I'm using TImage to display a png image.
When I restart Delphi and load the dpr file, TImage is still there, but the picture is lost,
requiring a reload of the picture before compiling.
At first I thought it's a path issue, so I loaded the picture from the same directory as the dpr, but it didn't help.
What else can I try?
Try this:
Open your project and your Form with
the PNG.
(Re)Load the PNG image.
Save and close your Form.
With a text editor, load your Form
DFM
I bet you don't have a big binary in
your TImage object, because the PNG content
has not been saved.
Bottom line, you'd have to include it as a resource and load it dynamically at runtime.
I ran into this problem as well with D2006. The solution I used is similar to François'.
I have a TPngImageCollection component that I collect all the images in at design time. You will need to find unit PngImageList off the web. The TPngImageCollection component has the advantage that you can have a collection of PNG images of differing sizes.
At run-time on startup, I assign the TImages from each of the collection members:
Image1.Picture.Assign (ImageCollection.Items [0].PNGImage) ;
Image2.Picture.Assign (ImageCollection.Items [1].PNGImage) ;
Image3.Picture.Assign (ImageCollection.Items [2].PNGImage) ;
etc
Bingo - you can produce your PNG originals with alpha transparency (I use PhotoPlus 6.0 from Serif - free and very capable) and show them in a TImage.

Resources