ImageEn for Delphi and C++ Builder ImageEn for Delphi and C++ Builder

 

ImageEn Forum
Profile    Join    Active Topics    Forum FAQ    Search this forumSearch
Forum membership is Free!  Click Join to sign-up
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 ImageEn Library for Delphi, C++ and .Net
 ImageEn and IEvolution Support Forum
 How to remove unused color from palette
 New Topic  Reply to Topic
Author Previous Topic Topic Next Topic  

zavf

Iran
22 Posts

Posted - May 24 2016 :  12:07:16  Show Profile  Reply
Hello dear friends

I am using ImageEN 5.2 (DCU Version) in Delphi XE 10.

I want to Remove UnUsed Colors from Color Table(or same Palette) and use this Code but this dont work :(




   procedure ConvertToOrdinal_8bit(PathToSave: string);
     var
      UsedColors: Integer;
      RGB_Palette: array of TRGB;
    begin
      with ImageEnView1 do
      begin
        UsedColors:= Proc.CalcImageNumColors;

        SetLength(RGB_Palette, UsedColors + 1);
        Proc.CalcImagePalette(RGB_Palette, UsedColors + 1);
        Proc.ConvertToPalette(UsedColors + 1, @RGB_Palette[0], ieOrdered);

        Refresh;
        Proc.Update;

        IO.Params.BitsPerSample := 8;
        IO.Params.SamplesPerPixel := 1;


        IO.SaveToFileBMP('c:\TestFile.bmp');
      end;
    end;



This Palette contain used colors and unused colors
https://i.imgsafe.org/aaac198.jpg



and This Palette contain only used colors
https://i.imgsafe.org/fc7e079.jpg

Thanks to help me

w2m

USA
1990 Posts

Posted - May 24 2016 :  17:06:40  Show Profile  Reply
Rather than removing unused colors I'd suggest setting the pixel format to ie8p then set the length of a TColorArray to the IEBitmap.PaletteLength then iterate through the IEBitmap.Palette to fill the TColorArray.

This will produce a list of the colors in the image.

uses ieview, imageenview, imageenproc, hyieutils, hyiedefs, iexBitmaps, GraphUtil;
            
procedure TForm1.GetPaletteColors;
{ Fill TColorArray with palette colors. }
var
   i: Integer;
   iColorList: TColorArray;
begin
   ImageEnView1.IO.LoadFromFile(OpenPictureDialog1.FileName);
   { If the bitmap is not 8 bit paletted then convert it }
    if ImageEnView1.IEBitmap.PixelFormat <> ie8p then
       ImageEnView1.IEBitmap.PixelFormat := ie8p;
    SetLength(iColorList, ImageEnView1.IEBitmap.PaletteLength);
    { Add the colors to the TColorArray }
    for i := 0 to ImageEnView1.IEBitmap.PaletteLength - 1 do
    begin
       iColorList[i].Value := TRGB2TColor(ImageEnView1.IEBitmap.Palette[i]);
       iColorList[i].Name := '';
    end;
    { sort the colors by HUE - Optional}
    SortColorArray(iColorList, 0, 0, stHue, False);
end;

Bill Miller
Adirondack Software & Graphics
Email: w2m@hughes.net
EBook: http://www.imageen.com/ebook/
Custom Commercial ImageEn Development
Go to Top of Page

zavf

Iran
22 Posts

Posted - May 24 2016 :  17:47:49  Show Profile  Reply
Thanks But i need change Bitmap palette and save file with used color in palette and unused color will be removed.

please help
Go to Top of Page

xequte

38947 Posts

Posted - May 24 2016 :  20:08:16  Show Profile  Reply
Hi

Can you also attach your source image?

Nigel
Xequte Software
www.xequte.com
nigel@xequte.com
Go to Top of Page

zavf

Iran
22 Posts

Posted - May 25 2016 :  11:23:20  Show Profile  Reply
Thanks xequte

This my Project with image bmp file (even or other bmp file same this problem)

in dir win32\debug file "Remove unused color by other software.pcx" its removed unused color by other software and I want to do this by imageEn.


Please see my project and help me

Download link project file compiled with xe10
https://www.mediafire.com/?1lt445v4bs6sqn2
Go to Top of Page

w2m

USA
1990 Posts

Posted - May 25 2016 :  12:55:23  Show Profile  Reply
My point is that you are loading the palette incorrectly. If you load the palette correctly there is no need to remove unused colors because there are no unused colors.

Here is some code that:

1. Correctly loads the palette from an image into a color grid Unused colors are not loaded.
procedure TForm1.Open1Click(Sender: TObject);
var
  i: Integer;
  iColor: TColor;
begin
  if OpenPictureDialog1.Execute then
    if FileExists(OpenPictureDialog1.FileName) then
    begin
      { In order to be able to load the image palette colors, LegacyBitmap must be
        false, NativePixelFormat must be true and the bitmap must be 8-bit
        paletted }
      { Do not use Windows Bitmaps }
      ImageEnView1.LegacyBitmap := False;
      { Load images in native format }
      ImageEnView1.IO.NativePixelFormat := true;
      ImageEnView1.IO.LoadFromFile(OpenPictureDialog1.FileName);
      { if the bitmap is not 8 bit paletted then convert it }
      if ImageEnView1.IEBitmap.PixelFormat <> ie8p then
        ImageEnView1.IEBitmap.PixelFormat := ie8p;
      for i := 0 to ImageEnView1.IEBitmap.PaletteLength - 1 do
      begin
        iColor := TRGB2TColor(ImageEnView1.IEBitmap.Palette[i]);
        {Add the palette color to the color grid }
        mbColorPalette1.Colors.Add(ColorToString(iColor));
      end;
       StatusBar1.Panels[0].Text := ExtractFileDir(OpenPictureDialog1.FileName);
       StatusBar1.Panels[1].Text := ExtractFileName(OpenPictureDialog1.FileName);
    end;
end;



2. Sets a selected palette color(s) to a new color value(s).

procedure TForm1.mbColorPalette1CellClick(Button: TMouseButton;
  Shift: TShiftState; index: Integer; AColor: TColor; var DontCheck: Boolean);
begin
  { Get the index of the selected color }
  AIndex := index;
  StatusBar1.Panels[2].Text := 'Index: ' + IntToStr(index);
end;

procedure TForm1.SetPaletteColors1Click(Sender: TObject);
begin
  { Set the selected color grid color to the new color }
  mbColorPalette1.Colors[AIndex] := ColorToString(ColorBox1.Selected);
  mbColorPalette1.Update;
  { Set the palette color to the new color }
  ImageEnView1.IEBitmap.Palette[AIndex] := TColor2TRGB(ColorBox1.Selected);
  ImageEnView1.Update;
end;



3. Save the modified image to a file.
procedure TForm1.SaveAs1Click(Sender: TObject);
begin
  if SavePictureDialog1.Execute then
  begin
    ImageEnView1.IO.SaveToFile(SavePictureDialog1.FileName);
    if ImageEnView1.IO.Aborting then
    begin
      MessageBox(0, 'The image was not saved correctly.', 'Warning', MB_ICONWARNING or MB_OK);
      exit;
    end;
    StatusBar1.Panels[0].Text := ExtractFileDir(SavePictureDialog1.FileName);
    StatusBar1.Panels[1].Text := ExtractFileName(SavePictureDialog1.FileName);
  end;
end;



Bill Miller
Adirondack Software & Graphics
Email: w2m@hughes.net
EBook: http://www.imageen.com/ebook/
Custom Commercial ImageEn Development
Go to Top of Page

zavf

Iran
22 Posts

Posted - May 26 2016 :  02:09:38  Show Profile  Reply
Thanks w2m

Please share this sample project
Go to Top of Page

w2m

USA
1990 Posts

Posted - May 26 2016 :  09:56:19  Show Profile  Reply
You may download a demo here:
http://www.imageen.com/ieforum/topic.asp?whichpage=5&TOPIC_ID=1446#9619
This demo requires downloadingt a color library that uses a color grid from the library or replace the color grid with your own and modify the source code accordingly to handle your color grid.

Bill Miller
Adirondack Software & Graphics
Email: w2m@hughes.net
EBook: http://www.imageen.com/ebook/
Custom Commercial ImageEn Development
Go to Top of Page

zavf

Iran
22 Posts

Posted - May 26 2016 :  10:35:31  Show Profile  Reply
w2M Please test my image file and give your result.
my image
https://www.mediafire.com/?3k3tzz8ybos1s88

my Result. unused color is not removed !

https://i.imgsafe.org/8101f62.jpg
Go to Top of Page

w2m

USA
1990 Posts

Posted - May 26 2016 :  11:08:20  Show Profile  Reply
As I have said many times, you can not remove a color. I suspect you do not understand how palette colors work. You can replace a palette color with an alternate color as shown in the demo. The demo does not remove any colors, it just changes them.

Bill Miller
Adirondack Software & Graphics
Email: w2m@hughes.net
EBook: http://www.imageen.com/ebook/
Custom Commercial ImageEn Development
Go to Top of Page

zavf

Iran
22 Posts

Posted - May 26 2016 :  13:08:10  Show Profile  Reply
Thanks w2m

Now how to do check color index uses in bitmap with this way I changed unused color to RGB(0,0,0) , it Ok
Go to Top of Page

w2m

USA
1990 Posts

Posted - May 26 2016 :  13:12:26  Show Profile  Reply
Show me the code you used to do this.

Bill Miller
Adirondack Software & Graphics
Email: w2m@hughes.net
EBook: http://www.imageen.com/ebook/
Custom Commercial ImageEn Development
Go to Top of Page

zavf

Iran
22 Posts

Posted - May 26 2016 :  13:33:45  Show Profile  Reply
In clearly I check color index in palette uses or not usesd.
Go to Top of Page

w2m

USA
1990 Posts

Posted - May 26 2016 :  13:34:50  Show Profile  Reply
Show me your code snippet please.

Bill Miller
Adirondack Software & Graphics
Email: w2m@hughes.net
EBook: http://www.imageen.com/ebook/
Custom Commercial ImageEn Development
Go to Top of Page

zavf

Iran
22 Posts

Posted - May 26 2016 :  18:24:05  Show Profile  Reply
sorry w2m

I need to check Palette[Index] its used in Bitmap?

This code work but very very very slow and finally image dont show correctly



       for i := 1 to ImageEnView1.IEBitmap.Width do
         for j := 1 to imageEnView1.IEBitmap.Height do
           colorlist.Add(ColorToString(TRGB2TColor(ImageEnView1.IEBitmap.Pixels[j, i])));




        for i := 0 to ImageEnView1.IEBitmap.PaletteLength - 1 do
        begin
          iColor := TRGB2TColor(ImageEnView1.IEBitmap.Palette[i]);
          if (colorlist.IndexOf(ColorToString(iColor)) > 0) then
            mbColorPalette1.Colors.Add(ColorToString(iColor))
          else
            Continue;
        end;



See Result
https://i.imgsafe.org/5d7e3f7.png


Thank you for Help Me.
Go to Top of Page

zavf

Iran
22 Posts

Posted - May 26 2016 :  20:26:11  Show Profile  Reply
finally i can add only used color but my way ist very very slow


for i := 0 to ImageEnView1.IEBitmap.PaletteLength - 1 do
        begin
          iColor := TRGB2TColor(ImageEnView1.IEBitmap.Palette[i]);
          ImageEnView1.SelectColors(TColor2TRGB(iColor));
          if ImageEnView1.Selected then
            mbColorPalette1.Colors.Add(ColorToString(iColor));
        end;
Go to Top of Page

zavf

Iran
22 Posts

Posted - May 27 2016 :  06:30:01  Show Profile  Reply
w2m can help me . my code its very very slow and some time my program become hang.
Go to Top of Page

zavf

Iran
22 Posts

Posted - May 27 2016 :  06:51:09  Show Profile  Reply
https://i.imgsafe.org/82681b4a74.jpg
Go to Top of Page

w2m

USA
1990 Posts

Posted - May 27 2016 :  11:10:03  Show Profile  Reply
You will increase the speed if you get pixel colors by using scanline... something like this:
function GetColorFromBmp(X, Y: Integer; Bmp: TIEBitmap): TColor;
var
  Line: pRGBTripleArray;
begin
  Line := Bmp.ScanLine[Y];
  Result := RGBtoColor(Line^[X].rgbtRed, Line^[X].rgbtGreen, Line^[X].rgbtBlue);
end;

Untested code

Bill Miller
Adirondack Software & Graphics
Email: w2m@hughes.net
EBook: http://www.imageen.com/ebook/
Custom Commercial ImageEn Development
Go to Top of Page

zavf

Iran
22 Posts

Posted - May 29 2016 :  14:37:37  Show Profile  Reply
Finally i do this

Only Get Used Color from TIEBitmap



    pRGBTripleArray = ^TRGBTripleArray;
    TRGBTripleArray = ARRAY[0..MaxPixelCount-1] OF TRGBTriple;


procedure GetColorList(const Bitmap: TIEBitmap; out UsedColorList: TStringList);
  var
    Flags:  array[byte, byte] OF TBits;
    i    :  Integer;
    j    :  Integer;
    k    :  Integer;
    rowIn:  pRGBTripleArray;
BEGIN
  for j := 0 to 255 do
    for i := 0 to 255 do
      Flags[i,j] := nil;

  UsedColorList.Sorted:= True;
  UsedColorList.Duplicates:= dupIgnore;

  for j := 0 TO Bitmap.Height-1 do
  begin
    Application.ProcessMessages;
    rowIn  := Bitmap.Scanline[j];
    for i := 0 TO Bitmap.Width-1 do
    begin
      with rowIn[i] do
      begin

        if  (not Assigned(Flags[rgbtRed, rgbtGreen])) then
        begin
          Flags[rgbtRed, rgbtGreen]:= TBits.Create;
          Flags[rgbtRed, rgbtGreen].Size:= 256;
        end;

        Flags[rgbtRed,rgbtGreen].Bits[rgbtBlue]:= True;
        UsedColorList.Add(ColorToString(RGB(rgbtRed, rgbtGreen, rgbtBlue)));

      end
    end
  end;
end;

Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
Jump To: