PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » PureBasic для Windows » GDI+: свойства изображения


GDI+: свойства изображения

Сообщений 1 страница 9 из 9

1

Застрял на коде с этой библиотекой

Код:
#GDIPLUS_OK = 0

  Enumeration
    #RotateNoneFlipNone
    #Rotate90FlipNone
    #Rotate180FlipNone
    #Rotate270FlipNone
    #RotateNoneFlipX
    #Rotate90FlipX
    #Rotate180FlipX
    #Rotate270FlipX
    #RotateNoneFlipY   = #Rotate180FlipX
    #Rotate90FlipY     = #Rotate270FlipX
    #Rotate180FlipY    = #RotateNoneFlipX
    #Rotate270FlipY    = #Rotate90FlipX
    #RotateNoneFlipXY  = #Rotate180FlipNone
    #Rotate90FlipXY    = #Rotate270FlipNone
    #Rotate180FlipXY   = #RotateNoneFlipNone
    #Rotate270FlipXY   = #Rotate90FlipNone
  EndEnumeration 

  Enumeration
    #EncoderParameterValueTypeByte          = 1
    #EncoderParameterValueTypeASCII         = 2
    #EncoderParameterValueTypeShort         = 3
    #EncoderParameterValueTypeLong          = 4
    #EncoderParameterValueTypeRational      = 5
    #EncoderParameterValueTypeLongRange     = 6
    #EncoderParameterValueTypeUndefined     = 7
    #EncoderParameterValueTypeRationalRange = 8
    #EncoderParameterValueTypePointer       = 9
  EndEnumeration 

;-Structures.
  Structure GdiplusStartupInput
    GdiPlusVersion.l 
    *DebugEventCallback.DebugEventProc
    SuppressBackgroundThread.l 
    SuppressExternalCodecs.l 
  EndStructure

  ;The following two structures are used for setting encoder parameters (in our case the 'quality' parameter).
    Structure EncoderParameter
      guid.GUID
      NumberOfValues.l
      Type.l
      Value.l
    EndStructure

    Structure EncoderParameters
      Count.i
      Parameter.EncoderParameter[1]
    EndStructure


;-Imports.
  Import "gdiplus.lib"
    GdiplusStartup(token, *input.GdiplusStartupInput, output) 
    GdiplusShutdown(token)
    GdipLoadImageFromFile(*filename, *bitmap)
    GdipImageRotateFlip(image, rotateFlipType)
    GdipSaveImageToFile(image, filename.p-unicode, *clsidEncoder.CLSID, *encoderParams)
    GdipDisposeImage(image)
    GdipGetAllPropertyItems(*image, totalBufferSize.l, numProperties.l, ai);ai is *allItems.PropertyItem
    GdipGetPropertySize(*image, totalBufferSize.i, numProperties.i)
  EndImport


  sourceFile$="d:\gdi+\photo_2025-02-18_14-38-49.jpg"
  ;Protected input.GdiplusStartupInput, encParams.EncoderParameters
    input.GdiplusStartupInput\GdiPlusVersion = 1
    GdiplusStartup(@token, @input, #Null)
    ;Was the initialisation successful?
      If token
        If GdipLoadImageFromFile(@sourceFile$, @image) = #GDIPLUS_OK
          
          rr=GdipGetPropertySize(@image, @totalBufferSize, @numProperties)
          Debug rr
          rr=gdipGetAllPropertyItems(@image,@sz,@np,*m)
           GdipDisposeImage(image)
         EndIf
;         ;Tidy up.
          GdiplusShutdown(token)
      EndIf


DataSection
;CLSID for the gdi+ jpeg encoder.
  clsid_jpeg:
    Data.l $557CF401
    Data.w $1A04, $11D3
    Data.b $9A, $73, $00, $00, $F8, $1E, $F3, $2E
;CLSID for the relevant gdi+ encoder parameter.
  clsid_EncoderQuality:
    Data.l $1D5BE4B5
    Data.w $FA4A, $452D
    Data.b $9C, $DD, $5D, $B3, $51, $05, $E7, $EB
EndDataSection

GdipGetPropertySize возвращает значение или 2 или 4 и дальше не работает. Хотелось бы знать, в чем причина.

0

2

egons написал(а):

Хотелось бы знать, в чем причина.

Функции нужен указатель, а не указатель на указатель.

Код:
rr=GdipGetPropertySize(image, @totalBufferSize, @numProperties)

0

3

rr=gdipGetAllPropertyItems(@image,@sz,@np,*m)
тоже результат 2.
Запутался я с этими описаниями функций

Отредактировано egons (18.02.2025 19:12:25)

0

4

Я же пишу просто указатель, а не указатель на указатель.

Код:
rr=gdipGetAllPropertyItems(image,@sz,@np,*m)

Функции GdipDisposeImage() передали то что нужно, а остальным нет.

0

5

Код:
;Private Declare Function GdipGetAllPropertyItems Lib "gdiplus" (ByVal image As Long, ByVal totalBufferSize As Long, ByVal numProperties As Long, ByRef allItems As PropertyItem) As Status
          rr=gdipGetAllPropertyItems(image,sz,np,*m)

Вроде бы все правильно, но не фунциклирует.

0

6

Крайний справа аргумент это массив структур PropertyItem. Его нужно создать в коде и функция его заполнит.
Здесь пример https://learn.microsoft.com/ru-ru/windo … pertyitems

0

7

тьху, так заработало

Код:
          rr=gdipGetAllPropertyItems(image,totalBufferSize,numProperties,*m)

  totalBufferSize,numProperties получаются из вызова функции.

Пётр, спасибо за помощь, иначе бы не понял. Сегодня не мой день(

0

8

Интересно, что для JPG текстовый маркер в Properties помечается как комментарий EXIF, хотя EXIF не существует. Для PNG не найдено text chunks.
Попробую разобраться  с добавлением комментариев к JPG

Код:
#GDIPLUS_OK = 0

Enumeration
  #RotateNoneFlipNone
  #Rotate90FlipNone
  #Rotate180FlipNone
  #Rotate270FlipNone
  #RotateNoneFlipX
  #Rotate90FlipX
  #Rotate180FlipX
  #Rotate270FlipX
  #RotateNoneFlipY   = #Rotate180FlipX
  #Rotate90FlipY     = #Rotate270FlipX
  #Rotate180FlipY    = #RotateNoneFlipX
  #Rotate270FlipY    = #Rotate90FlipX
  #RotateNoneFlipXY  = #Rotate180FlipNone
  #Rotate90FlipXY    = #Rotate270FlipNone
  #Rotate180FlipXY   = #RotateNoneFlipNone
  #Rotate270FlipXY   = #Rotate90FlipNone
EndEnumeration 

Enumeration
  #EncoderParameterValueTypeByte          = 1
  #EncoderParameterValueTypeASCII         = 2
  #EncoderParameterValueTypeShort         = 3
  #EncoderParameterValueTypeLong          = 4
  #EncoderParameterValueTypeRational      = 5
  #EncoderParameterValueTypeLongRange     = 6
  #EncoderParameterValueTypeUndefined     = 7
  #EncoderParameterValueTypeRationalRange = 8
  #EncoderParameterValueTypePointer       = 9
EndEnumeration 

;-Structures.
Structure GdiplusStartupInput
  GdiPlusVersion.l 
  *DebugEventCallback.DebugEventProc
  SuppressBackgroundThread.l 
  SuppressExternalCodecs.l 
EndStructure

;The following two structures are used for setting encoder parameters (in our case the 'quality' parameter).
Structure EncoderParameter
  guid.GUID
  NumberOfValues.l
  Type.l
  Value.l
EndStructure

Structure EncoderParameters
  Count.i
  Parameter.EncoderParameter[1]
EndStructure

Structure PropertyItem
  id.l;                 // ID of this property
  length.l;             // Length of the property value, in bytes
  type.u  ;               // Type of the value, as one of TAG_TYPE_XXX
  padding.w
  *value
EndStructure


;-Imports.
Import "gdiplus.lib"
  GdiplusStartup(token, *input.GdiplusStartupInput, output) 
  GdiplusShutdown(token)
  GdipLoadImageFromFile(*filename, *bitmap)
  GdipImageRotateFlip(image, rotateFlipType)
  GdipSaveImageToFile(image, filename.p-unicode, *clsidEncoder.CLSID, *encoderParams)
  GdipDisposeImage(image)
  GdipGetAllPropertyItems(*image, totalBufferSize.l, numProperties.l, ai);ai is *allItems.PropertyItem
  GdipGetPropertySize(*image, totalBufferSize.i, numProperties.i)
EndImport


sourceFile$="d:\gdi+\photo_2025-02-18_14-38-49.jpg"
;sourceFile$="d:\gdi+\1584812707-a92e3f716beaa04c7000e8afc3b87b59.png"

input.GdiplusStartupInput\GdiPlusVersion = 1
GdiplusStartup(@token, @input, #Null)
;Was the initialisation successful?
If token
  If GdipLoadImageFromFile(@sourceFile$, @image) = #GDIPLUS_OK
    totalBufferSize=0
    numProperties=0
    If GdipGetPropertySize(image, @totalBufferSize, @numProperties) = #GDIPLUS_OK
      If totalBufferSize And numProperties
        *m=AllocateMemory(totalBufferSize)
        rr=gdipGetAllPropertyItems(image,totalBufferSize, numProperties,*m)
        ;     CreateFile(0,"prop.bin")
        ;     WriteData(0,*m,totalBufferSize)
        ;     CloseFile(0)
        *pp.PropertyItem=AllocateMemory(SizeOf(PropertyItem))
        For i=0 To numProperties-1
          CopyMemory(*m+i*SizeOf(PropertyItem),*pp,SizeOf(PropertyItem))
          Debug "id="+Hex(*pp\id)+",len="+Str(*pp\length)+",type="+Str(*pp\type);;+",value="+Str(pp\*value)
          If *pp\type=2
            Debug PeekS(*pp\value,*pp\length,#PB_Ascii);ShowMemoryViewer(*pp\value, 1024)
          EndIf
        Next i
        FreeMemory(*pp)
        FreeMemory(*m)
      EndIf
    EndIf;If GdipGetPropertySize
    
    GdipDisposeImage(image)
  EndIf
  ;         ;Tidy up.
  GdiplusShutdown(token)
EndIf


DataSection
  ;CLSID for the gdi+ jpeg encoder.
  clsid_jpeg:
  Data.l $557CF401
  Data.w $1A04, $11D3
  Data.b $9A, $73, $00, $00, $F8, $1E, $F3, $2E
  ;CLSID for the relevant gdi+ encoder parameter.
  clsid_EncoderQuality:
  Data.l $1D5BE4B5
  Data.w $FA4A, $452D
  Data.b $9C, $DD, $5D, $B3, $51, $05, $E7, $EB
EndDataSection

0

9

Комментарии к JPG в текстовом виде не пишутся, только EXIF

Код:
;https://www.purebasic.fr/english/viewtopic.php?t=49026

Structure GdiplusStartupInput
  GdiPlusVersion.l 
  *DebugEventCallback.DebugEventProc
  SuppressBackgroundThread.l 
  SuppressExternalCodecs.l 
EndStructure

Structure PropertyItem
  id.l;                 // ID of this property
  length.l;             // Length of the property value, in bytes
  type.u  ;               // Type of the value, as one of TAG_TYPE_XXX
  padding.w
  *value
EndStructure

;The following two structures are used for setting encoder parameters (in our case the 'quality' parameter).
Structure EncoderParameter
  guid.GUID
  NumberOfValues.l
  Type.l
  Value.l
EndStructure

Structure EncoderParameters
  Count.i
  Parameter.EncoderParameter[1]
EndStructure

Import "gdiplus.lib"
  GdiplusStartup(token, *input.GdiplusStartupInput, output) 
  GdiplusShutdown(token)
  GdipLoadImageFromFile(*filename, *bitmap)
  GdipImageRotateFlip(image, rotateFlipType)
  GdipSaveImageToFile(image, filename.p-unicode, *clsidEncoder.CLSID, *encoderParams)
  GdipDisposeImage(image)
  GdipGetAllPropertyItems(*image, totalBufferSize.l, numProperties.l, ai);ai is *allItems.PropertyItem
  GdipGetPropertySize(*image, totalBufferSize.i, numProperties.i)
  GdipCreateBitmapFromHBITMAP(hbm.i, hpal.i, bitmap)
  GdipSetPropertyItem(*image, *pi)
EndImport

path$ = GetCurrentDirectory()+"ttest.jpg"

; Make an image to test with
CreateImage(0, 640,640)
StartDrawing(ImageOutput(0))
  Box(0,0,640,640,#White)
  Circle(319,319,319,#Blue)
  Circle(319,319,219,#Green)
  Circle(319,319,119,#Yellow)
StopDrawing()


#EncoderParameterValueTypeLong = 4

;Define Unicode$=Space(Len(path$)*2+2), path_as_bstr, lib
;Define bmp.BITMAP,input.GdiplusStartupInput, *token, *image
;PokeS(@Unicode$, path$, -1, #PB_Unicode) 
;path_as_bstr = SysAllocString_(@Unicode$) 

input.GdiplusStartupInput\GdiPlusVersion=1 
GdiplusStartup(@*token, @input, #Null)

; Here is where we have a gdiplus image object that we want to save as jpeg with selectable quality
GdipCreateBitmapFromHBITMAP(ImageID(0), 0, @*image)

quality.l = 100 ; qualities can range from 0 - 100, with 100 being best
With encoderparams.EncoderParameters
  \Count = 1
  \Parameter[0]\Type = #EncoderParameterValueTypeLong
  \Parameter[0]\NumberOfValues = 1
  \parameter[0]\Value = @quality
EndWith
CopyMemory(?clsid_EncoderQuality, encoderparams\parameter[0]\Guid, SizeOf(GUID))

c$="simple text"
#PropertyTagImageTitle = $0320
#PropertyTagExifUserComment=$9286
#PropertyTagTypeASCII = 2
*NewTitle.PropertyItem=AllocateMemory(SizeOf(PropertyItem))
NewTitle.s = Space(MemoryStringLength(@c$, #PB_Ascii))
PokeS(@NewTitle, c$, -1, #PB_Ascii)

*NewTitle\id = #PropertyTagExifUserComment;#PropertyTagImageTitle
*NewTitle\length=Len(c$)+1
*NewTitle\type = #PropertyTagTypeASCII
*NewTitle\value = @NewTitle
rr=GdipSetPropertyItem(*image, *NewTitle)
Debug rr
FreeMemory(*NewTitle)
result = GdipSaveImageToFile(*image, path$, ?clsid_jpeg, encoderparams)

GdipDisposeImage(image)
GdiplusShutdown(token)

DataSection
  clsid_jpeg: ; clsid for jpeg image format
  Data.l $557CF401
  Data.w $1A04
  Data.w $11D3
  Data.b $9A,$73,$00,$00,$F8,$1E,$F3,$2E
  
  clsid_EncoderQuality:
  Data.l $1D5BE4B5
  Data.w $FA4A
  Data.w $452D
  Data.b $9C,$DD,$5D,$B3,$51,$05,$E7,$EB
EndDataSection

0


Вы здесь » PureBasic - форум » PureBasic для Windows » GDI+: свойства изображения