Forum > Other
fpGUI:How to add image for fpgbutton
lazpas:
How do I associate a custom image for fpgbutton?
Thanks for help.
Graham1:
Sorry for such a late reply.
I think you need to start by using the imageconvert tool in FPGUI to change your BMP (not PNG) image file into data, for example:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---const newimg_rotate: array[0..821] of byte = ( $42,$4D,$36,$03,$00,$00,$00,$00,$00,$00,$36,$00,$00,$00,$28,$00,$00, $00,$10,$00,$00,$00,$10,$00,$00,$00,$01,$00,$18,$00,$00,$00,$00,$00, $00,$03,$00,$00,$C4,$0E,$00,$00,$C4,$0E,$00,$00,$00,$00,$00,$00,$00, $00,$00,$00,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$CC,$CC,$CC,$27,$27,$27,$05,$05,$05,$8C,$8C,$8C,$FF,$FF,$FF,$A8, $A8,$A8,$DA,$DA,$DA,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$A8,$A8,$A8,$DA,$DA,$DA,$B4,$B4, $B4,$05,$05,$05,$1C,$1C,$1C,$9F,$9F,$9F,$CC,$CC,$CC,$00,$00,$00,$05, $05,$05,$9F,$9F,$9F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$75,$75,$75,$00,$00,$00,$53,$53,$53,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$89,$89,$89,$0C,$0C,$0C,$75, $75,$75,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $0C,$0C,$0C,$13,$13,$13,$D4,$D4,$D4,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$F9,$F9,$F9,$FF,$FF,$FF,$96, $96,$96,$D4,$D4,$D4,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$D0,$D0,$D0, $DE,$DE,$DE,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$DA,$DA,$DA,$00,$00,$00,$32, $32,$32,$FF,$FF,$FF,$E9,$E9,$E9,$4A,$4A,$4A,$B8,$B8,$B8,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$2E,$2E,$2E,$00,$00,$00,$E9, $E9,$E9,$A8,$A8,$A8,$00,$00,$00,$73,$73,$73,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$CC,$CC,$CC,$9A,$9A,$9A,$FF,$FF,$FF,$9A, $9A,$9A,$00,$00,$00,$84,$84,$84,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$B0,$B0,$B0,$00, $00,$00,$66,$66,$66,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$E7,$E7,$E7,$00,$00,$00,$1C, $1C,$1C,$F9,$F9,$F9,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$DE,$DE, $DE,$BC,$BC,$BC,$E1,$E1,$E1,$FF,$FF,$FF,$4A,$4A,$4A,$00,$00,$00,$89, $89,$89,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$F9,$F9,$F9, $72,$72,$72,$4A,$4A,$4A,$27,$27,$27,$05,$05,$05,$00,$00,$00,$00,$00, $00,$B4,$B4,$B4,$FF,$FF,$FF,$D4,$D4,$D4,$05,$05,$05,$05,$05,$05,$9F, $9F,$9F,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$53,$53,$53, $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$21,$21,$21,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$A8,$A8,$A8,$05,$05,$05,$00,$00,$00,$4A, $4A,$4A,$B0,$B0,$B0,$E1,$E1,$E1,$DE,$DE,$DE,$9F,$9F,$9F,$00,$00,$00, $00,$00,$00,$00,$00,$00,$00,$00,$00,$89,$89,$89,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$BC,$BC,$BC,$21,$21,$21,$00,$00,$00,$00, $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00, $00,$00,$00,$05,$05,$05,$EC,$EC,$EC,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$F9,$F9,$F9,$A8,$A8,$A8,$60,$60,$60,$3D, $3D,$3D,$3D,$3D,$3D,$60,$60,$60,$A8,$A8,$A8,$7B,$7B,$7B,$00,$00,$00, $60,$60,$60,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF, $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$4A,$4A,$4A,$CC,$CC,$CC, $FF,$FF,$FF,$FF,$FF,$FF);
Then when you create your button you can use:
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- fpgImages.AddMaskedBMP( 'newimg.rotate', @newimg_rotate, sizeof(newimg_rotate), 0,0); MyButton := TfpgButton.Create(Self); with MyButton do begin Name := 'MyButton'; Left := 10; Top := 10; Width := 24; Height := 24; Text := ''; ImageName:='newimg.rotate'; ShowImage := True; ImageLayout:=ilImagetop; end;
Graham1:
The problem with the above method is that you need CONST data for every size of button image, regardless of whether you use it at runtime.
Here's another way to do it, using the BGRA package and a PNG file in Resources. Note that the mask for the PNG is the top left pixel, so it works best if that is the same colour as your button. I use a 128x128 PNG as that allows for most sized buttons. The PNG file can't have transparency.
Requires package BGRABitmapPack4fpGUI.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---uses Classes, SysUtils, fpg_base, fpg_main, fpg_form, fpg_button, BGRABitmapTypes, BGRABitmap;
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---// OLD VERSION - see the post below for an updateprocedure FPGAddMask(ResName:string; MaskId:string; siz:integer);var ResPng : TBGRABitmap; WrkBmp : TBGRABitmap; ImgArr : array of byte; InStream : TFileStream; i, cnt : integer; b : byte = 0;begin ResPng:=TBGRABitmap.Create; ResPng.LoadFromResource(ResName); WrkBmp:=TBGRABitmap.Create; BGRAReplace(WrkBmp, ResPng.Resample(siz, siz, rmFineResample)); WrkBmp.SaveToFile('tempwork.bmp'); InStream := TFileStream.Create('tempwork.bmp', fmOpenRead); try InStream.Seek(0, soFromBeginning); cnt:=InStream.Size; ImgArr:=[]; setlength(ImgArr, cnt); for i:=0 to cnt-1 do begin InStream.Read(b, 1); ImgArr[i]:=b; end; finally InStream.Free; end; DeleteFile('tempwork.bmp'); fpgImages.AddMaskedBMP( MaskId, @ImgArr[0], cnt, 0,0); ResPng.Free; WrkBmp.Free; end;
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} --- FPGAddMask('PNG_RES_NAME','myImgId',16); MyButton := TfpgButton.Create(Self); with MyButton do begin Name := 'MyButton'; Left := 10; Top := 10; Width := 24; Height := 24; Text := ''; ImageMargin=1; ImageName:='myImgId'; ShowImage := True; ImageLayout:=ilImagetop; end;
But now I have a question. How can I create the byte array without writing the image to a temporary file on disk first? It slows things down using the HDD and I think it's an ugly way of doing it. I tried to find the source code for SaveToFile but it seems to be buried in classes of classes.
TRon:
--- Quote from: Graham1 on July 27, 2024, 02:17:35 am ---But now I have a question. How can I create the byte array without writing the image to a temporary file on disk first?
--- End quote ---
Usually by using SaveToStream, for example writing to a (temp) MemoryStream. TMemoryStream has a pointer to its memory that can be used.
Graham1:
--- Quote from: TRon on July 27, 2024, 02:29:57 am ---Usually by using SaveToStream, for example writing to a (temp) MemoryStream. TMemoryStream has a pointer to its memory that can be used.
--- End quote ---
Thank you! I didn't know about TMemoryStream but that was the solution, although I'm not sure about the "pointer to its memory" bit. Now I have the following and it works fine.
--- Code: Pascal [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure FPGAddMask(ResName:string; MaskId:string; siz:integer);var ResPng : TBGRABitmap; WrkStream : TMemoryStream; ImgArr : array of byte; i, cnt : integer; b : byte = 0;begin ResPng:=TBGRABitmap.Create; ResPng.LoadFromResource(ResName); BGRAReplace(ResPng, ResPng.Resample(siz, siz, rmFineResample)); WrkStream:=TMemoryStream.Create; ResPng.SaveToStreamAs(WrkStream, ifBmp); try WrkStream.Seek(0, soFromBeginning); cnt:=WrkStream.Size; ImgArr:=[]; setlength(ImgArr, cnt); for i:=0 to cnt-1 do begin WrkStream.Read(b, 1); ImgArr[i]:=b; end; finally WrkStream.Free; end; fpgImages.AddMaskedBMP( MaskId, @ImgArr[0], cnt, 0,0); ResPng.Free; end;
Thank you again.
Navigation
[0] Message Index
[#] Next page