Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > OOP
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 05-03-2020
SaraTorres SaraTorres is offline
Miembro
 
Registrado: sep 2017
Posts: 25
Poder: 0
SaraTorres Va por buen camino
Question Extraer un icono con el index

Saludos chicos

Tengo 1 icono con imágenes de diferentes tamaños (256x256, 128x128, 64x64...)

¿Cómo puedo extraer cada imagen a png (index) que hay dentro de 1 icono?

Se los agradezco de antemano.
Responder Con Cita
  #2  
Antiguo 06-03-2020
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.278
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Busca ejemplos sobre PrivateExtractIcons.
En este caso te permite extraer iconos del tamaño especificado sea cual sea el que le especifiques. El icono extraído lo obtendrás a partir del existente en el fichero que mejor se ajusta.

Si el fichero contiene un 64x64 y lo pides ese tamaño te dará ese, si le pides un 72x72 y el mayor que hay en el fichero es un 64x64, te lo generará a partir de ese.


Si no encuentras dímelo, creo que tengo por ahí algunas pruebas antiguas.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #3  
Antiguo 07-03-2020
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Es posible que de este hilo saques ideas.


Saludos.
Responder Con Cita
  #4  
Antiguo 07-03-2020
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Quizás esto te aclare un poco más las cosas. Te presento una función que extrae un icono determinado de un archivo de icono que porta más de una imagen.
Quizás lo apetecible sea hacerlo con la API ExtractIcon o incluso con ExtractIconEx pero ninguna de las dos acierta con el numero exacto de imágenes que tiene un archivo ico. Así que he escrito una función a bajo nivel que los busca, identifica uno por su índice y lo guarda en solitario en otro archivo ico.



Este es el código y las estructuras necesarias:


Código Delphi [-]
type

{$ALIGN 1}
TICONDIRENTRY = record
   bWidth: BYTE;               // Width of the image
   bHeight: BYTE;              // Height of the image (times 2)
   bColorCount: BYTE;          // Number of colors in image (0 if >=8bpp)
   bReserved: BYTE;            // Reserved
   wPlanes: WORD;              // Color Planes
   wBitCount: WORD;            // Bits per pixel
   dwBytesInRes: DWORD;        // how many bytes in this resource?
   dwImageOffset: DWORD;       // where in the file is this image
end; PICONDIRENTRY = ^TICONDIRENTRY;

type TICONDIR = record
   idReserved: WORD; // Reserved
   idType: WORD;     // resource type (1 for icons)
   idCount: WORD;    // how many images?
   idEntries: array[0..0] of TICONDIRENTRY; // the entries for each image
end; PICONDIR = ^TICONDIR;

type tagICONIMAGE= record
   icHeader: BITMAPINFOHEADER;       // DIB header
   icColors: array[0..0] of RGBQUAD; // Color table
   icXORarray: array[0..0] of BYTE;  // DIB bits for XOR mask
   icANDarray: array[0..0] of BYTE;  // DIB bits for AND mask
end; PICONIMAGE = ^tagICONIMAGE;
{$ALIGN OFF}


Código Delphi [-]
function ExtractIconFromFile(SourceFileName, DestFileName: String; Index: integer): integer;
var
  Stream, SDest: TMemoryStream;
  IconDir, IconDirDest: PICONDIR;
  AllSize: integer;
  SImage, DImage: PBYTE;
begin
  Stream:= TMemoryStream.Create;
  SDest:=  TMemoryStream.Create;
  Stream.LoadFromFile(SourceFileName);
  IconDir:= Stream.Memory;
  Result:= IconDir.idCount;
  if Index < Result then
  begin
    AllSize:= sizeof(ICONDIR) + IconDir.idEntries[index].dwBytesInRes;
    SDest.SetSize(AllSize);
    IconDirDest:= SDest.Memory;
    IconDirDest.idReserved:= 0;
    IconDirDest.idType:= 1;
    IconDirDest.idCount:= 1;
    IconDirDest.idEntries[0]:= IconDir.idEntries[index];
    IconDirDest.idEntries[0].dwImageOffset:= sizeof(TICONDIR) + sizeof(TICONDIRENTRY);
    SImage:= Stream.Memory;
    inc(SImage, IconDir.idEntries[index].dwImageOffset);
    DImage:= SDest.Memory;
    inc(DImage, IconDirDest.idEntries[0].dwImageOffset);
    CopyMemory(DImage, SImage, IconDir.idEntries[index].dwBytesInRes);
    SDest.SaveToFile(DestFileName);
  end;
  Stream.Free;
  SDest.Free;
end;


La función devuelve el número de iconos encontrado, si el índice es menor que ese número, guarda ese icono en un archivo. Si el indice es -1 o el no hay nombre de archivo de salida, simplemente devuelve el número de iconos encontrado.



Ejemplo de uso:
Código Delphi [-]
var
  IconCount: integer;
begin
  IconCount:= ExtractIconFromFile('icon.ico', 'p2.ico', 2);
end;




Saludos.
Responder Con Cita
  #5  
Antiguo 08-03-2020
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.197
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Y para continuar con la respuesta, te muestro cómo guardar la imagen de un icono localizado por su índice en un archivo png utilizando GDI+ Flat API. El código esta escrito y compilado con delphi7


Código Delphi [-]
type

{$ALIGN 1}
TICONDIRENTRY = record
   bWidth: BYTE;               // Width of the image
   bHeight: BYTE;              // Height of the image (times 2)
   bColorCount: BYTE;          // Number of colors in image (0 if >=8bpp)
   bReserved: BYTE;            // Reserved
   wPlanes: WORD;              // Color Planes
   wBitCount: WORD;            // Bits per pixel
   dwBytesInRes: DWORD;        // how many bytes in this resource?
   dwImageOffset: DWORD;       // where in the file is this image
end; PICONDIRENTRY = ^TICONDIRENTRY;

type TICONDIR = record
   idReserved: WORD; // Reserved
   idType: WORD;     // resource type (1 for icons)
   idCount: WORD;    // how many images?
   idEntries: array[0..0] of TICONDIRENTRY; // the entries for each image
end; PICONDIR = ^TICONDIR;

type tagICONIMAGE= record
   icHeader: BITMAPINFOHEADER;       // DIB header
   icColors: array[0..0] of RGBQUAD; // Color table
   icXORarray: array[0..0] of BYTE;  // DIB bits for XOR mask
   icANDarray: array[0..0] of BYTE;  // DIB bits for AND mask
end; PICONIMAGE = ^tagICONIMAGE;
{$ALIGN OFF}



TCLSID = TGUID;
PCLSID = ^TCLSID;
TImageCodecInfo = packed record
   Clsid:             TCLSID;
   FormatID:          TGUID;
   CodecName:         PWCHAR;
   DllName:           PWCHAR;
   FormatDescription: PWCHAR;
   FilenameExtension: PWCHAR;
   MimeType:          PWCHAR;
   Flags:             DWORD;
   Version:           DWORD;
   SigCount:          DWORD;
   SigSize:           DWORD;
   SigPattern:        PBYTE;
   SigMask:           PBYTE;
end;
PImageCodecInfo = ^TImageCodecInfo;

TEncoderParameter = packed record
   Guid:           TGUID;
   NumberOfValues: ULONG;
   Type_:          ULONG;
   Value:          Pointer;
end;
PEncoderParameter = ^TEncoderParameter;

TEncoderParameters = packed record
   Count     : UINT;
   Parameter : array[0..0] of TEncoderParameter;
end;
PEncoderParameters = ^TEncoderParameters;

function  wcscmp(wstr1, wstr2: PWCHAR): Integer; cdecl external 'crtdll';

// GDI+ Flat API...
function  GdiplusStartup(var GdiToken: DWORD; Startup, Output: PBYTE): Cardinal; stdcall external 'gdiplus';
procedure GdiplusShutdown(GdiToken: DWORD); stdcall external 'gdiplus';
function  GdipCreateBitmapFromHICON(Icon: HICON; var GBitmap: THANDLE): Cardinal; stdcall external 'gdiplus';
function  GdipCreateBitmapFromHBITMAP(hbm: HBITMAP; hpal: HPALETTE; var GBitmap: THANDLE): Cardinal; stdcall external 'gdiplus';
function  GdipGetImageEncodersSize(var numEncoders: DWORD; var size: DWORD): Cardinal; stdcall external 'gdiplus';
function  GdipGetImageEncoders(numEncoders, size: DWORD; encoders: PImageCodecInfo): Cardinal; stdcall external 'gdiplus';
function  GdipDisposeImage(image: THANDLE): Cardinal; stdcall external 'gdiplus';
function  GdipSaveImageToFile(image: THANDLE; FileName: PWCHAR; var clsidEncoder: TCLSID; encoderParams: Pointer): Cardinal; stdcall external 'gdiplus';


Código Delphi [-]
// Calidad de imagen y factor de compresión
// Quality = 100 es la maxima calidad.
procedure GetEncoderParameters(EP: PEncoderParameters; Quality: PULONG);
const
  EncoderQuality: TGUID = '{1d5be4b5-fa4a-452d-9cdd-5db35105e7eb}';
begin
  EP.Count:= 1;
  EP.Parameter[0].Guid:= EncoderQuality;
  EP.Parameter[0].Type_:= 4; //Gdiplus::EncoderParameterValueTypeLong;
  EP.Parameter[0].NumberOfValues:= 1;
  EP.Parameter[0].Value:= Quality;
end;
 
// Obtener el CLSID para la codificación de un formato gráfico
function GetEncoderClsid(Format: PWCHAR; var Clsid: TCLSID): boolean;
var
  i, N, Size: Cardinal;
  ICInfo: array of TImageCodecInfo;
begin
  i:= 0; N:= 0; Size:= 0;
  GdipGetImageEncodersSize(N, Size);
  if Size > 0 then
  begin
    SetLength(ICInfo, Size);
    GdipGetImageEncoders(N, Size, @ICInfo[0]);
    while (i < N) and (wcscmp(ICInfo[i].MimeType, Format)<>0) do inc(i);
    if i < N then Clsid:= ICInfo[i].Clsid;
  end;
  Result:= boolean(i < N);
end;

//---------------------------------------------------------------------------
// Guarda un HBITMAP en un archivo con un formato gráfico determinado
procedure SaveIconToFile(Icon: HICON; FileName, Format: PWCHAR; Quality: ULONG=100);
var
  gdiplusToken: DWORD;
  GdiPlusStartupInput: array[0..2] of int64;

  Clsid: TCLSID;
  EP: TEncoderParameters;
  GBitmap: THANDLE;
begin
  // Inicializamos GDI+.
  GdiPlusStartupInput[0]:= 1; GdiPlusStartupInput[1]:= 0;
  if GdiplusStartup(gdiplusToken, @GdiPlusStartupInput, nil) <> 0 then exit;

  GetEncoderClsid(Format, Clsid);
  GetEncoderParameters(@EP, @Quality);

  GdipCreateBitmapFromHICON(Icon, GBitmap);

  GdipSaveImageToFile(GBitmap, FileName, Clsid, @EP);
  GdipDisposeImage(GBitmap);

  // Shutdown GDI+
  GdiplusShutdown(gdiplusToken);
end;



// Encuentra una imagen de icono y la guarda como png
function IconToPng(IconFileName, PngFileName: String; index: integer): integer;
var
  Stream, SDest: TMemoryStream;
  IconDir, IconDirDest: PICONDIR;
  AllSize: integer;
  SImage, DImage: PBYTE;
  Icon: TIcon;
begin
  Stream:= TMemoryStream.Create;
  SDest:=  TMemoryStream.Create;
  Stream.LoadFromFile(IconFileName);
  IconDir:= Stream.Memory;
  Result:= IconDir.idCount;
  if (Index >= 0) and (Index < Result) and (PngFileName <> '') then
  begin
    AllSize:= sizeof(ICONDIR) + IconDir.idEntries[index].dwBytesInRes;
    SDest.SetSize(AllSize);
    IconDirDest:= SDest.Memory;
    IconDirDest.idReserved:= 0;
    IconDirDest.idType:= 1;
    IconDirDest.idCount:= 1;
    IconDirDest.idEntries[0]:= IconDir.idEntries[index];
    IconDirDest.idEntries[0].dwImageOffset:= sizeof(TICONDIR) + sizeof(TICONDIRENTRY);
    SImage:= Stream.Memory;
    inc(SImage, IconDir.idEntries[index].dwImageOffset);
    DImage:= SDest.Memory;
    inc(DImage, IconDirDest.idEntries[0].dwImageOffset);
    CopyMemory(DImage, SImage, IconDir.idEntries[index].dwBytesInRes);
    Icon:= TIcon.Create;
    SDest.Position:= 0;
    Icon.LoadFromStream(SDest);
    SaveIconToFile(Icon.Handle, PWChar(WideString(PngFileName)), 'image/png');
    Icon.Free;
  end;
  Stream.Free;
  SDest.Free;
end;


En realidad la función SaveIconToFile es mucho más potente pues puede guardar el icono en cualquiera de los formatos que admite GDI+ (BMP, GIF, JPEG, PNG, TIFF, WMF, EMF e ICON).



Saludos.

Última edición por escafandra fecha: 08-03-2020 a las 00:06:34.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Index is out of date... index table torito Conexión con bases de datos 7 10-12-2016 13:21:31
Extraer icono de archivo .exe Caroso Varios 8 16-08-2013 11:52:32
Extraer el icono de un archivo dec Trucos 0 30-06-2006 23:53:43
Index,...!!! 3 Rikardote Conexión con bases de datos 2 28-12-2004 13:05:00
extraer un icono gemma Varios 10 28-06-2003 11:45:26


La franja horaria es GMT +2. Ahora son las 06:27:02.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi