Solved

Drawing a highlighted bitmap

Posted on 2001-06-04
11
324 Views
Last Modified: 2013-12-03
I want to draw a highlighted bitmap like
the explorer when you select a item (with icon).
Does anyone knows how can i do that?
0
Comment
Question by:bugroger
11 Comments
 
LVL 9

Expert Comment

by:ginsonic
ID: 6154938
Can you give me more details , please?
0
 
LVL 14

Expert Comment

by:DragonSlayer
ID: 6155284
listening...
0
 
LVL 2

Author Comment

by:bugroger
ID: 6155371
more details:

ex.
 When you click on an exe-file in the explorer
 the text changed to clHighlightText/clhighlight
 and the icon from the exe-file will be displayed
 darker.


 How can I "convert" a normal icon/bitmap to such
 a "darker" icon/bitmap?


0
 
LVL 2

Author Comment

by:bugroger
ID: 6155811
I found the ImgList_DrawEx function.

With this function you can draw a "selcected Bitmap".
So you can write a function which convert a Bitmap to
a "darker" bitmap.


0
 
LVL 33

Expert Comment

by:Slick812
ID: 6157531
hello bugroger, here is some code that I used to TRY to simulate the Icon hilighting used in windows explorer windows. This uses a PatBlt with the dwRop set to $A000C9, which might be undocumented, it is a pixel blending dwRop operation. I never got an exact match for the windows highlighting operation, but this was close enough for me to use as a visual image highlighting method.

private
bmp: TBitmap;


procedure TForm1.FormCreate(Sender: TObject);
var
i, k, Dot: Integer;
begin
{this creates a 8x8 bitmap for your Brush, I put it in create because I used this bmp many, many times}
bmp:= TBitmap.Create;
  With bmp Do
  Begin
  width := 8;
  height:= 8;
  PixelFormat := pf24Bit;
  Dot := 0;
  for i:= 0 to 7 do
  begin
    for k:= 0 to 7 do
    if ((k+ Dot) mod 2) <> 0 then
    canvas.Pixels[k,i] := clSilver
    else
    canvas.Pixels[k,i] := GetSysColor(COLOR_HIGHLIGHT)};
{if you don't need the same color highlight as windows, you can try clGray here or your own color}
    Inc(Dot)
  end;
    End;

end;

procedure TForm1.Button_HiLiteClick(Sender: TObject);
var
FirstPic: TBitmap;
begin
if OpenpictureDialog1.Execute then
  begin
  FirstPic := TBitmap.Create;
  FirstPic.LoadFromFile(OpenpictureDialog1.FileName);
{if the bitmap is not 24 Bit then colors will be blocky}
  FirstPic.PixelFormat := pf24bit;
{set brush bitmap to the one you created}
  FirstPic.Canvas.Brush.Bitmap := bmp;

{you can try FirstPic.Canvas.Brush.Color := clHighlight ,
 and you don't need the bmp or bitmap brush at all,
but this didn't look close enough to the windows highlight for me}

{this will blend the FirstPic with the bmp brush, and then it's ready to use}
  PatBlt(FirstPic.Canvas.Handle, 0, 0, FirstPic.Width, FirstPic.Height, $A000C9);
  Canvas.Draw(0,0,FirstPic); // use bitmap
  FirstPic.Free;
  end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
bmp.Free;
end;

- - - - - - - - - - - - - - - - - - - - - -
there must be an undocumented dwRop for the windows highlighting operation, but I couldn't find it.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 33

Expert Comment

by:Slick812
ID: 6158116
correction, I should have put this

for k:= 0 to 7 do
    if ((k+ Dot) mod 2) <> 0 then
    canvas.Pixels[k,i] := $00AAAAAA
    else
    canvas.Pixels[k,i] := clHightLight;
0
 
LVL 2

Author Comment

by:bugroger
ID: 6158859
I have written my own function to highlight a bitmap.
I have used ALPHA-BLENDING to realized that.

NewRed    = Rs*Sr+Rd*Dr
NewGreen  = Gs*Sg+Gd*Dg
NewBlue   = Bs*Sb+Bd*Db
NewFactor = As*Sa+Ad*Da

  Rs=FactorSourceRed    | Sr=SourceRed     |
  Rd=FactorDestRed      | Dr=DestRed

  Gs=FactorSourceGreen  | Sg=SourceGreen   |
  Gd=FactorDestGreen    | Dg=DestGreen
     
  Bs=FactorSourceBlue   | Sb=SourceBlue    |
  Bd=FactorDestBlue     | Db=DestBlue

  As=FactorSourceFactor | Sa=SourceFactor  |
  Ad=FactorDestFactor   | Da=DestFactor


//Alpha 0.0 - 1.0
Procedure BlendWithColor(Src, Dest : TBitmap; BlendColor : TColor; Alpha : Real);
TYPE
 TRGB = record
         r, g, b, PALType : Byte;
        end;
 TpRGB = packed record
          b, g, r : Byte;
         end;

VAR
 BlendColorChannels : TRGB;
 DestRGBPixel       : ^TpRGB;
 SrcRGBPixel        : ^TpRGB;
 y, x               : Integer;
 SourceColorFaktor  : real;

Begin
 //Set BitPerPixel -> 24Bit
 Src.PixelFormat  := pf24Bit;
 Dest.PixelFormat := pf24Bit;
 Dest.Width       := Src.Width;
 Dest.Height      := Src.Height;


 //Get RGB-Channels from Color
 BlendColorChannels := TRGB(BlendColor);
 IF BlendColorChannels.PalType = 128 then
  BlendColorChannels := TRGB(GetSysColor((BlendColor AND $0000FFFF)));

 //Get SourceColorFaktor
 SourceColorFaktor := 1.0 - Alpha;

 //Get all Pixels
 For y := 0 to Dest.Height -1 do
 Begin
  //Get Pixel
  SrcRGBPixel  := Src.ScanLine[y];
  DestRGBPixel := Dest.ScanLine[y];
  For x := 0 to Dest.Width -1 do
  Begin
   DestRGBPixel.r := Round(SourceColorFaktor * SrcRGBPixel.r  + Alpha * BlendColorChannels.r);
   DestRGBPixel.g := Round(SourceColorFaktor * SrcRGBPixel.g  + Alpha * BlendColorChannels.g);
   DestRGBPixel.b := Round(SourceColorFaktor * SrcRGBPixel.b  + Alpha * BlendColorChannels.b);
 
   //Set Pointer to next Pixel
   Inc(DestRGBPixel);
   Inc(SrcRGBPixel);
  End;
 End;
End;
0
 
LVL 33

Expert Comment

by:Slick812
ID: 6162005
well bugroger, I like your code and it works real good, but its not an exact match for the windows icon highlighting effect, at least not on my puters. I got very close results with the alpha set to  .61 - I added a line to help the highlighted look with dark colors

For x := 0 to Dest.Width -1 do
 Begin
  if SrcRGBPixel.r + SrcRGBPixel.g + SrcRGBPixel.b < 64 then
  begin
  DestRGBPixel.r := SrcRGBPixel.r;
  DestRGBPixel.g := SrcRGBPixel.g;
  DestRGBPixel.b := SrcRGBPixel.b;
  end else
  begin
  DestRGBPixel.r := Round(SourceColorFaktor * SrcRGBPixel.r  + Alpha * BlendColorChannels.r);
  DestRGBPixel.g := Round(SourceColorFaktor * SrcRGBPixel.g  + Alpha * BlendColorChannels.g);
  DestRGBPixel.b := Round(SourceColorFaktor * SrcRGBPixel.b  + Alpha * BlendColorChannels.b);
  end;
  //Set Pointer to next Pixel
  Inc(DestRGBPixel);
  Inc(SrcRGBPixel);
 End;

- - - - - - -
good work
0
 
LVL 2

Author Comment

by:bugroger
ID: 6162936
Here is my new code to get an exact match
for the "windows icon highlighting effect."

I have used ROUND(INT(......))...

 For y := 0 to Dest.Height -1 do
 Begin
  //Get Pixel
  SrcRGBPixel  := Src.ScanLine[y];
  DestRGBPixel := Dest.ScanLine[y];
  For x := 0 to Dest.Width -1 do
  Begin

    DestRGBPixel.r := ROUND(INT(SourceColorFaktor *     SrcRGBPixel.r  + BlendingColorFaktor *        BlendColorChannels.r));
    DestRGBPixel.g := ROUND(INT(SourceColorFaktor *      SrcRGBPixel.g  + BlendingColorFaktor *       BlendColorChannels.g));
    DestRGBPixel.b := ROUND(INT(SourceColorFaktor * SrcRGBPixel.b  + BlendingColorFaktor * BlendColorChannels.b));

   //Set Pointer to next Pixel
   Inc(DestRGBPixel);
   Inc(SrcRGBPixel);
  End;
 
0
 
LVL 33

Accepted Solution

by:
Slick812 earned 100 total points
ID: 6165783
this looks like a match for me
 - - - - - -

var
Dot: Integer;

Dot := 0;
For x := 0 to Dest.Width -1 do
 Begin
  if ((x+ Dot) mod 2) = 0 then
  begin
  DestRGBPixel.r := Round(0.38 * SrcRGBPixel.r  + 0.4 * BlendColorChannels.r);
  DestRGBPixel.g := Round(0.38 * SrcRGBPixel.g  + 0.4 * BlendColorChannels.g);
  DestRGBPixel.b := Round(0.38 * SrcRGBPixel.b  + 0.4 * BlendColorChannels.b);
  end else
  begin
  DestRGBPixel.r := Round(0.38 * SrcRGBPixel.r  + 0.62 * BlendColorChannels.r);
  DestRGBPixel.g := Round(0.38 * SrcRGBPixel.g  + 0.62 * BlendColorChannels.g);
  DestRGBPixel.b := Round(0.38 * SrcRGBPixel.b  + 0.62 * BlendColorChannels.b);
  end;
  //Set Pointer to next Pixel
  Inc(DestRGBPixel);
  Inc(SrcRGBPixel);

 End;
 Inc(Dot);
End;
0
 
LVL 6

Expert Comment

by:edey
ID: 6484042
Actually, if you look very carefully at a "selected" icon you can see that it's just had a mask drawn over it like this:

* * * * * * * *
 * * * * * * *
* * * * * * * *
 * * * * * * *
* * * * * * * *
 * * * * * * *
* * * * * * * *

where the spaces are transparent & the *'s are dark blue.  You could (if you've already got the "checkerboard" mask) do this with a couple of blts:

bmp.canvas.copyMode := cmMergeCopy;
bmp.canvas.draw(0,0,mask_bmp);
bmp.canvas.copymode := cmMergePaint;
bmp.canvas.draw(0,0,mask_bmp);


GL
Mike
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now