In my Delphi XE3 Application I've placed a TPageControl component into the MainForm.
I linked its "Images" property to a ImageList which contains some PNG images.
At design time when I set the "Image Index" properties of each TTabSheet the images are correctly represented. Otherwise, when I run the application I see that all the images contained in the TTabSheet (which should be without background) are surrounded by a black squared area.
I check the settings of my ImageList and I see that:
-BkColor: clNone
-BlendColor: clNone
-ColorDepth: cd32bit
-DrawingStyle: dsTransparent
-ImageType: itImage
-Masked: False
I don't know whether it will be relevant to the problem but I note that changing the settings of the Project and enabling the voice "Enable runtime theme" this problem is solved.
Thanks.
Related
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.
I want to load a PNG with transparent background in a TImageList and use it in a TMainMenu (via TAction).
However, in Delphi the background is just black.
This guy says it worked for him, but with a button instead of a main menu.
My setup:
My image is 8 bit per color plus 8 bit for transparency channel (I have tried also with 1 bit for transparency but still doesn't work). The image looks just fine in any other program.
Delphi XE.
In TImageList's editor, the 'transparent color' and 'Fill color' are set to 'Default' and are disabled.
There's no reason to backup whole DFM file.
Before doing something to your ImageList you should export your images: click the "Export" button in the image list editor and it will save all images to a single .BMP file.
After changing properties: ColorDepth = cd32Bit, DrawingStyle = dsTransparent
You should click "Add" button and select the file you previously exported. Then, images will be drawn with transparency in the menu and toolbars (on D2010 at least)... No need to use 3rd party components.
Set the following property values for TImageList:
DrawingStyle: dsTransparent
ColorDepth: cd32Bit
TImageList's editor -> set the 'transparent color' to True
In "Project Settings" under "Application" set "Enable runtime themes".
Update for Delphi Rio:
TImageList must have:
BkGColor = clNone
BlendColor = clNone,
ColorDepth = cd32bit,
DrawingStyle = dsTransparent (or) dsNormal,
Masked = true.
The images can be loaded from a PNG with transparent bkg color.
Note: Editing some properties of TImageList will delete (without any notice) all existing images in your list. Backup your images (or DFM) first.
I had been using TPngComponents since Delphi 7. That provide very good png support for most of the delphi build-in / third party components. Embarcadero had purchased another well know Open Sources PNG Supporting component know as TPngImage and build into Delphi's native graphic support in later Delphi versions. So when I changed to Delphi 2010, I think Delphi had native support now and test out the native support but find that the alpha support is not good enough.
So I had used back that TPngComponents again and it had better support for most components, including main menu. I think that package should be usable to DXE with limited modification.
edit : Thanks for Uwe Raabe for pointing out the product Codegear (now Embarcadero) purchased was another component TPngImage rather then the TPngComponent.
I'm getting the system imagelist (with SHGetFileInfo and SHGFI_LARGEICON), adding two of my own icons and attaching it to a TListView.
The problem is that if the user's icon size isn't set to 32x32 (like it's set to 48x48 for example) the Delphi7 TImageList fails with an "Invalid image size" error.
Does anyone know if a workaround is available? I've tried using TPngImageList but it leads to other issues.
Also, please note that I'd like to preserve the Alpha channel of the icons. Normal 1-bit transparency is not enough, as icons tend to look ugly that way.
Thanks!
I'm not aware of any limitation on the size of images that TImageList can hold. It sounds to me that your problem is that you have icons of different sizes and you can't hold icons of different sizes in the same image list.
If you are working with icons of different sizes then you are going to need to grow the smaller ones in size. You'll have to build it up in code, using a bitmap. You fill the bitmap with pure transparent alpha channel and then blt the smaller icon onto the centre of the bitmap.
Another option would be to maintain two separate image lists but if you need to draw the icons into the same list view then I think that won't get the job done. My guess is that you'll need to grow the small icons.
For alpha, you're going to need to create the image list handle yourself because the ColorDepth property doesn't exist in D7. Because of this, a vanilla D7 TImageList simply cannot support icons with alpha channels.
You work around this limitation by calling ImageList_Create, passing ILC_COLOR32 and assigning the result to ImageList.Handle. Do this before you add any images. You'll have to populate the list at run time rather than design time, but it sounds like you are already doing that.
Here's a screen shot of a 48x48 tool button with a 32bpp icon with alpha transparency:
It's true that I made this in D2010, but my above workaround will work for D7 – I used that mechanism until quite recently with D6. I'm just showing this to prove that the image list can hold 48px icons. Since TImageList is just a wrapper around the system image list component, I believe what you are attempting should be perfectly feasible.
Just when I was about to give up this page led me to the solution:
http://delphihaven.wordpress.com/2010/09/06/custom-drawing-on-glass-2/
Apparently, if you try to add an icon that is bigger than 32x32 to a timagelist in Delphi7, the VCL will give you an "Invalid image size" error while it could simply call the himagelist API - which can easily handle it.
Here is the complete solution:
unit ImageListFix;
interface
uses CommCtrl, Graphics, ImgList;
type
TImageListFixer = class(TCustomImageList)
public
function AddIcon(Image: TIcon): Integer;
end;
implementation
function TImageListFixer.AddIcon(Image: TIcon): Integer;
begin
if Image = nil then
Result := Add(nil, nil)
else
begin
Result := ImageList_AddIcon(Handle, Image.Handle);
Change;
end;
end;
end.
And the code for adding icons to the system imagelist:
DocumentImgList:=TImageListFixer(GetSystemLargeIconsList);
IconToAdd:=TIcon.Create;
try
IconToAdd.Handle := LoadImage(0, 'c:\Ico1.ico', IMAGE_ICON, DocumentImgList.Width, DocumentImgList.Height, LR_LOADFROMFILE);
DocumentImgList.AddIcon(IconToAdd);
IconToAdd.Handle := LoadImage(0, 'c:\Ico2.ico', IMAGE_ICON, DocumentImgList.Width, DocumentImgList.Height, LR_LOADFROMFILE);
DocumentImgList.AddIcon(IconToAdd);
finally
IconToAdd.Free;
end;
TImageList raises an "Invalid image size" error under only 2 conditions:
1) The TImageList's Height or Width property is less than 1, or the Height property is greater than 32768, when the TImageList is initially created via the CreateSize() constructor (there are no such limitations imposed by the Height and Width property setters).
2) you try to add/insert a new TBitmap or TIcon whose dimensions do not fit within TImageList's internal image.
I'm using Delphi 2006. I have a few PNG images with transparencies and I have to create a GUI using them (top bar, left panel...). The images have different aligns properties. One of the images is the background of the form. The problem here is that I can't align it as alClient because it only occupies the rectangular zone that the other images have left, showing the naked canvas in their transparent zones. What I need is that the background image is put behind all the other images and taking all the canvas size.
Is there anyway to do this? I know I can do this writting some logic in the OnResize event of the form but I was just curious if I was missing something.
Thanks.
Put a TImage on the form and align it with "alClient". Then put an "alClient" aligned Panel on the form. The TPanel is transparent when themes are enabled and "ParentBackground" property is set. Then put the images on the panel and align them at will. If when themes are not enabled is important, you can use a "TJvPanel" which is part of the JVCL library. A search on google also seems to reveal some code for transparent panels.
The above will not help transparency with the "png"s though. AFAIK png support (transparency) is added with D2009 and I don't know if this support includes TImage.
edit: Actually it appears that I owe the very capability to load png images to TImage to the JVCL library itself, and it seems to support transparent "png"s with TImage just fine.
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.