Save *.tiff images natively...

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
griz
Enthusiast
Enthusiast
Posts: 167
Joined: Sun Jun 29, 2003 7:32 pm
Location: Canada

Post by griz »

Are you suggesting a mechanism to extract the dpi information in file formats like TIFF, without having to write one yourself?
Hmmmm... I'm quoting myself :?

Photoshop stores DPI information in Jpegs too, so this is not just about TIFFs.

Either ...

we explore these file formats ourselves and find a way to extract this information from the headers, or...

Fred does. he he

Is a new command like imagedpi() what you're after Kale?
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post by Kale »

Is a new command like imagedpi() what you're after Kale?
Yeah, and a way to save tiffs from PB. :)
--Kale

Image
El_Choni
TailBite Expert
TailBite Expert
Posts: 1007
Joined: Fri Apr 25, 2003 6:09 pm
Location: Spain

Post by El_Choni »

You can save TIFFs using GDI+, but it doesn't allow you to set the resolution, either. I coded this little procedure to set the dpi resolution of a single image TIFF file. Could you check if it works with your TIFFs?

Enable inline ASM:

Code: Select all

Structure Seeker
  StructureUnion
    b.b
    w.w
    l.l
  EndStructureUnion
EndStructure

Procedure Rev16(value.w)
  ProcedureReturn ((value&$FF00)>>8)|((value&$FF)<<8)
EndProcedure

Procedure Rev32(value)
  MOV eax, value
  BSWAP eax
  ProcedureReturn
EndProcedure

Procedure SetTIFFResolution(file$, dpi)
  hFile = OpenFile(#PB_Any, file$)
  If hFile
    TIFFSize = Lof()
    If TIFFSize>$9A
      *TIFF = AllocateMemory(Lof())
      ReadData(*TIFF, TIFFSize)
      *TIFFSeek.Seeker = *TIFF
      Select *TIFFSeek\w
        Case 'MM'
          dpi = Rev32(dpi)
          *TIFFSeek+4
          IFDOffset = Rev32(*TIFFSeek\l)
          inch = Rev16(2)
          den = Rev32(1)
          rv = 1
        Case 'II'
          *TIFFSeek+4
          IFDOffset = *TIFFSeek\l
          inch = 2
          den = 1
          rv = 0
        Default
          CloseFile(hFile)
          ProcedureReturn #FALSE
      EndSelect
      *TIFFSeek = *TIFF+IFDOffset
      If TIFFSize>IFDOffset+2
        If rv:FieldCount = Rev16(*TIFFSeek\w):Else:FieldCount = *TIFFSeek\w:EndIf
        If FieldCount
          *TIFFSeek+2
          For i=0 To FieldCount-1
            If *TIFFSeek<*TIFF+TIFFSize-2
              If rv:Tag = Rev16(*TIFFSeek\w):Else:Tag = *TIFFSeek\w:EndIf
              Select Tag
                Case 282 ; XResolution
                  *TagSeek.Seeker = *TIFFSeek+8
                  If rv:ValueOffset = Rev32(*TagSeek\l):Else:ValueOffset = *TagSeek\l:EndIf
                  If ValueOffset<=TIFFSize-8
                    PokeL(*TIFF+ValueOffset, dpi)
                    PokeL(*TIFF+ValueOffset+4, den)
                    xrelDone = 1
                  EndIf
                Case 283 ; YResolution
                  *TagSeek = *TIFFSeek+8
                  If rv:ValueOffset = Rev32(*TagSeek\l):Else:ValueOffset = *TagSeek\l:EndIf
                  If ValueOffset<=TIFFSize-8
                    PokeL(*TIFF+ValueOffset, dpi)
                    PokeL(*TIFF+ValueOffset+4, den)
                    yrelDone = 1
                  EndIf
                Case 296 ; ResolutionUnit
                  PokeW(*TIFFSeek+8, inch)
                  ruDone = 1
              EndSelect
              *TIFFSeek+12
            EndIf
          Next i
        EndIf
        If ruDone&yrelDone&xrelDone
          FileSeek(0)
          WriteData(*TIFF, TIFFSize)
          result = #TRUE
        EndIf
      EndIf
    EndIf
    CloseFile(hFile)
  EndIf
  ProcedureReturn result
EndProcedure

dpi = 150
TIFFFile$ = OpenFileRequester("", "", "", 0)
If TIFFFile$
  Debug SetTIFFResolution(TIFFFile$, dpi)
EndIf
El_Choni
El_Choni
TailBite Expert
TailBite Expert
Posts: 1007
Joined: Fri Apr 25, 2003 6:09 pm
Location: Spain

Post by El_Choni »

Here, the code to load bmp and save it as tiff setting its resolution, combining the above code with GDI+ code:

GDI+ is included with Windows XP, and freely downloadable (and probably freely distributable, check this) from http://www.microsoft.com and compatible with Windows 98 and ahead. It's not guaranteed to work in Windows 95.

Usage:

Code: Select all

SaveTIFF(ImageID, TIFFFileName$, compression, dpi)
compression can be one of the following values:

Code: Select all

#EncoderValueCompressionLZW = 2
#EncoderValueCompressionCCITT3 = 3
#EncoderValueCompressionCCITT4 = 4
#EncoderValueCompressionRle = 5
#EncoderValueCompressionNone = 6
The code (enable inline ASM):

Code: Select all

Structure ErrorCode
  section.l
  value.l
EndStructure

#WindowsError = 0
#ImageViewerError = 1
#GdiError = 2

Procedure Error(message.s, *code.ErrorCode, fatal.b)
  Select *code\section
    Case #ImageViewerError
      CodeMessage$ = "ImageViewer error: unknown"
    Case #GdiError
      Select *code\value
        Case 0
          ErrorBuffer$ = Space(1024)
          FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError_(), 0, ErrorBuffer$, Len(ErrorBuffer$), 0)
          CodeMessage$ = ErrorBuffer$
        Case 1
          CodeMessage$ = "Generic error"
        Case 2
          CodeMessage$ = "Invalid parameter"
        Case 3
          CodeMessage$ = "Out of memory"
        Case 4
          CodeMessage$ = "Object busy"
        Case 5
          CodeMessage$ = "Insufficient buffer"
        Case 6
          CodeMessage$ = "Not implemented"
        Case 7
          ErrorBuffer$ = Space(1024)
          FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError_(), 0, ErrorBuffer$, Len(ErrorBuffer$), 0)
          CodeMessage$ = "Win32 Error: "+ErrorBuffer$
        Case 8
          CodeMessage$ = "Wrong state"
        Case 9
          CodeMessage$ = "Aborted"
        Case 10
          CodeMessage$ = "File not found"
        Case 11
          CodeMessage$ = "Value overflow"
        Case 12
          CodeMessage$ = "Access denied"
        Case 13
          CodeMessage$ = "Unknown image format"
        Case 14
          CodeMessage$ = "Font family not found"
        Case 15
          CodeMessage$ = "Font style not found"
        Case 16
          CodeMessage$ = "Not TrueType font"
        Case 17
          CodeMessage$ = "Unsupported Gdiplus version"
        Case 18
          CodeMessage$ = "Gdiplus not initialized"
        Case 19
          CodeMessage$ = "Property not found"
        Case 20
          CodeMessage$ = "Property not supported"
      EndSelect
    Default
      ErrorBuffer$ = Space(1024)
      FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError_(), 0, ErrorBuffer$, Len(ErrorBuffer$), 0)
      CodeMessage$ = ErrorBuffer$
  EndSelect
  MessageRequester("Error", message+Chr(10)+Chr(10)+CodeMessage$, 0)
  If fatal
    End
  EndIf
EndProcedure

Structure GdiplusStartupInput
  GdiplusVersion.l
  DebugEventCallback.l
  SuppressBackgroundThread.l
  SuppressExternalCodecs.l
EndStructure

Structure CLSID
  Data1.l
  Data2.w[2]
  Data3.b[8]
EndStructure

Structure MyGUID
  Data1.l
  Data2.w[2]
  Data3.b[8]
EndStructure

Structure ImageCodecInfo
  Clsid.CLSID         ; Codec identifier.
  FormatID.MyGUID     ; File format identifier. GUIDs that identify various file formats (ImageFormatBMP, ImageFormatEMF, And the like) are defined in Gdiplusimaging.h. 
  CodecName.s         ; WCHAR * Pointer To a null-terminated string that contains the codec name. 
  DllName.s           ; WCHAR * Pointer To a null-terminated string that contains the path name of the DLL in which the codec resides. If the codec is not in a DLL, this pointer is NULL.
  FormatDescription.s ; WCHAR * Pointer To a null-terminated string that contains the name of the file format used by the codec. 
  FilenameExtension.s ; WCHAR * Pointer To a null-terminated string that contains all file-name extensions associated with the codec. The extensions are separated by semicolons.
  MimeType.s          ; WCHAR * Pointer To a null-terminated string that contains the mime type of the codec. 
  Flags.l             ; DWORD  Combination of flags from the ImageCodecFlags enumeration. 
  Version.l           ; DWORD  Integer that indicates the version of the codec. 
  SigCount.l          ; DWORD  Integer that indicates the number of signatures used by the file format associated with the codec. 
  SigSize.l           ; DWORD  Integer that indicates the number of bytes in each signature. 
  SigPattern.l        ; BYTE * Pointer To an array of bytes that contains the pattern For each signature. 
  SigMask.l           ; BYTE * Pointer To an array of bytes that contains the mask For each signature. 
EndStructure

#EncoderParameterValueTypeLong = 4

#EncoderValueCompressionLZW = 2
#EncoderValueCompressionCCITT3 = 3
#EncoderValueCompressionCCITT4 = 4
#EncoderValueCompressionRle = 5
#EncoderValueCompressionNone = 6

Structure EncoderParameter
  Guid.MyGUID
  NumberOfValues.l
  Type.l
  Value.l
EndStructure

Structure EncoderParameters
  Count.l
  Parameter1.EncoderParameter
;  Parameter2.EncoderParameter
EndStructure

Global Gdiplus, gdiplusToken, bitmap, hbmReturn, encoderClsid, width, height, num, size
Global *GdiplusStartup, *GdiplusShutdown, *GdipSaveImageToFile, *GdipGetImageEncodersSize
Global *GdipGetImageEncoders, *GdipCreateBitmapFromHBITMAP

Procedure GdiStart()
  Gdiplus = OpenLibrary(0, "GDIPLUS.DLL")
  If Gdiplus
    CoInitialize_(#NULL)
    *GdiplusStartup = IsFunction(0, "GdiplusStartup")
    If *GdiplusStartup
      gdpsi.GdiplusStartupInput
      gdpsi\GdiplusVersion = 1
      gdpsi\DebugEventCallback = 0
      gdpsi\SuppressBackgroundThread = 0
      gdpsi\SuppressExternalCodecs = 0
      CallFunctionFast(*GdiplusStartup, @gdiplusToken, gdpsi, #NULL)
      If gdiplusToken
        *GdipGetImageEncodersSize = IsFunction(0, "GdipGetImageEncodersSize")
        *GdipGetImageEncoders = IsFunction(0, "GdipGetImageEncoders")
        *GdipCreateBitmapFromHBITMAP = IsFunction(0, "GdipCreateBitmapFromHBITMAP")
        *GdipSaveImageToFile = IsFunction(0, "GdipSaveImageToFile")
        *GdiplusShutdown = IsFunction(0, "GdiplusShutdown")
        If (*GdipGetImageEncodersSize And *GdipGetImageEncoders And *GdipCreateBitmapFromHBITMAP And *GdipSaveImageToFile And *GdiplusShutdown)=0
          Gdiplus = 0
        EndIf
      Else
        Gdiplus = 0
      EndIf
    Else
      Gdiplus = 0
    EndIf
  Else
    Gdiplus = 0
  EndIf
  ProcedureReturn Gdiplus
EndProcedure

Procedure GdiEnd()
  If Gdiplus
    CallFunctionFast(*GdiplusShutdown, gdiplusToken)
    CoUninitialize_()
  EndIf
EndProcedure

Procedure GetEncoderClsid(Format$, *Clsid)
  Gerror.ErrorCode
  result = 0
  num = 0
  size = 0
  FormatWSize = (Len(Format$)*2)+2
  *FormatW = CoTaskMemAlloc_(FormatWSize)
  If *FormatW
    If MultiByteToWideChar_(#CP_ACP, 0, Format$, -1, *FormatW, Len(Format$)+1)
      CallFunctionFast(*GdipGetImageEncodersSize, @num, @size)
      If size
        *ImageCodecInfoArray = CoTaskMemAlloc_(size)
        If *ImageCodecInfoArray
          result = CallFunctionFast(*GdipGetImageEncoders, num, size, *ImageCodecInfoArray)
          If result=#S_OK
            For j=0 To num-1
              *pImageCodecInfo.ImageCodecInfo = *ImageCodecInfoArray+(SizeOf(ImageCodecInfo)*j);*ImageCodecInfoArray+((size/num)*j)
              If CompareMemory(*pImageCodecInfo\MimeType, *FormatW, FormatWSize)
                PokeL(*Clsid, *pImageCodecInfo\Clsid)
                result = j
              EndIf
            Next j
          Else
            ErrorMessage$ = "GdipGetImageEncoders() failed."
          EndIf
          CoTaskMemFree_(*pImageCodecInfo)
        Else
          Gerror\section = #WindowsError
          Error("CoTaskMemAlloc_() failed.", Gerror, 0)
        EndIf
      Else
        ErrorMessage$ = "GdipGetImageEncodersSize() failed."
      EndIf
    Else
      Gerror\section = #WindowsError
      Error("MultiByteToWideChar_() failed.", Gerror, 0)
    EndIf
    CoTaskMemFree_(*FormatW)
  Else
    Gerror\section = #WindowsError
    Error("CoTaskMemAlloc_() failed.", Gerror, 0)
  EndIf
  If ErrorMessage$
    Gerror\section = #GdiError
    Gerror\value = result
    Error(ErrorMessage$, Gerror, 0)
    result = 0
  EndIf
  ProcedureReturn result
EndProcedure

Procedure GdiSave(File$, hbm, compression)
  Gerror.ErrorCode
  If GetEncoderClsid("image/tiff", @encoderClsid)
    FileWSize = (Len(File$)*2)+2
    *FileW = CoTaskMemAlloc_(FileWSize)
    If *FileW
      If MultiByteToWideChar_(#CP_ACP, 0, File$, -1, *FileW, Len(File$)+1)
        If hbm
          eP.encoderParameters
          encoderParams = eP
          eP\Count = 1 ; 2
          CopyMemory(?EncoderCompression, eP\Parameter1\Guid, SizeOf(MyGUID))
          eP\Parameter1\Type = #EncoderParameterValueTypeLong
          eP\Parameter1\NumberOfValues = 1
          eP\Parameter1\Value = @compression
          bitmap = 0
          result = CallFunctionFast(*GdipCreateBitmapFromHBITMAP, hbm, 0, @bitmap)
          If result=#S_OK And bitmap
            If FileSize(File$)
              DeleteFile(File$)
            EndIf
            result = CallFunctionFast(*GdipSaveImageToFile, bitmap, *FileW, encoderClsid, encoderParams)
            If result<>#S_OK
              ErrorMessage$ = "GdipSaveImageToFile() failed."
            EndIf
          Else
            ErrorMessage$ = "GdipCreateBitmapFromHBITMAP() failed."
          EndIf
        EndIf
      Else
        Gerror\section = #WindowsError
        Error("MultiByteToWideChar_() failed.", Gerror, 0)
      EndIf
      CoTaskMemFree_(*FileW)
    Else
      Gerror\section = #WindowsError
      Error("CoTaskMemAlloc_() failed.", Gerror, 0)
    EndIf
  Else
    Gerror\section = #ImageViewerError
    Error("GetEncoderCLSID() procedure failed.", Gerror, 0)
  EndIf
  If ErrorMessage$
    Gerror\section = #GdiError
    Gerror\value = result
    Error(ErrorMessage$, Gerror, 0)
    result = 0
  Else
    result = 1
  EndIf
  ProcedureReturn result
EndProcedure

Structure Seeker
  StructureUnion
    b.b
    w.w
    l.l
  EndStructureUnion
EndStructure

Procedure Rev16(value.w)
  ProcedureReturn ((value&$FF00)>>8)|((value&$FF)<<8)
EndProcedure

Procedure Rev32(value)
  MOV eax, value
  BSWAP eax
  ProcedureReturn
EndProcedure

Procedure SetTIFFResolution(file$, dpi)
  Gerror.ErrorCode
  hFile = OpenFile(#PB_Any, file$)
  If hFile
    TIFFSize = Lof()
    If TIFFSize>$9A
      *TIFF = AllocateMemory(Lof())
      ReadData(*TIFF, TIFFSize)
      *TIFFSeek.Seeker = *TIFF
      Select *TIFFSeek\w
        Case 'MM'
          dpi = Rev32(dpi)
          *TIFFSeek+4
          IFDOffset = Rev32(*TIFFSeek\l)
          inch = Rev16(2)
          den = Rev32(1)
          rv = 1
        Case 'II'
          *TIFFSeek+4
          IFDOffset = *TIFFSeek\l
          inch = 2
          den = 1
          rv = 0
        Default
          Gerror\section = #ImageViewerError
          Error("Not a TIFF file.", Gerror, 0)
          CloseFile(hFile)
          ProcedureReturn #FALSE
      EndSelect
      *TIFFSeek = *TIFF+IFDOffset
      If TIFFSize>IFDOffset+2
        If rv:FieldCount = Rev16(*TIFFSeek\w):Else:FieldCount = *TIFFSeek\w:EndIf
        If FieldCount
          *TIFFSeek+2
          For i=0 To FieldCount-1
            If *TIFFSeek<*TIFF+TIFFSize-2
              If rv:Tag = Rev16(*TIFFSeek\w):Else:Tag = *TIFFSeek\w:EndIf
              Select Tag
                Case 282 ; XResolution
                  *TagSeek.Seeker = *TIFFSeek+8
                  If rv:ValueOffset = Rev32(*TagSeek\l):Else:ValueOffset = *TagSeek\l:EndIf
                  If ValueOffset<=TIFFSize-8
                    PokeL(*TIFF+ValueOffset, dpi)
                    PokeL(*TIFF+ValueOffset+4, den)
                    xrelDone = 1
                  EndIf
                Case 283 ; YResolution
                  *TagSeek = *TIFFSeek+8
                  If rv:ValueOffset = Rev32(*TagSeek\l):Else:ValueOffset = *TagSeek\l:EndIf
                  If ValueOffset<=TIFFSize-8
                    PokeL(*TIFF+ValueOffset, dpi)
                    PokeL(*TIFF+ValueOffset+4, den)
                    yrelDone = 1
                  EndIf
                Case 296 ; ResolutionUnit
                  PokeW(*TIFFSeek+8, inch)
                  ruDone = 1
              EndSelect
              *TIFFSeek+12
            EndIf
          Next i
        Else
          Gerror\section = #ImageViewerError
          Error("Field count not found.", Gerror, 0)
        EndIf
        If ruDone&yrelDone&xrelDone
          FileSeek(0)
          WriteData(*TIFF, TIFFSize)
          result = #TRUE
        Else
          Gerror\section = #ImageViewerError
          Error("Resolution fields not found.", Gerror, 0)
        EndIf
      Else
        Gerror\section = #ImageViewerError
        Error("Offset past end of file.", Gerror, 0)
      EndIf
    Else
      Gerror\section = #ImageViewerError
      Error("IFDOffset past end of file.", Gerror, 0)
    EndIf
    CloseFile(hFile)
    ProcedureReturn result
  Else
    Gerror\section = #WindowsError
    Error("Can't open file.", Gerror, 0)
  EndIf
  ProcedureReturn #FALSE
EndProcedure

Procedure SaveTIFF(ImageID, file$, compression, dpi)
  If GDISave(file$, ImageID, compression)
    result = SetTIFFResolution(file$, dpi)
  EndIf
  ProcedureReturn result
EndProcedure

ImageFile$ = OpenFileRequester("Open image file", "", "Bitmap file (*.bmp)|*.bmp", 0)
If ImageFile$
  hImage = LoadImage(0, ImageFile$)
  TIFFFile$ = SaveFileRequester("Save TIFF file", Left(ImageFile$, Len(ImageFile$)-Len(GetExtensionPart(ImageFile$))-1)+".tiff", "TIFF image file (*.tiff;*.tif)|*.tiff;*.tif", 0)
  If TIFFFile$
    If GdiStart()
      compression = #EncoderValueCompressionLZW
;        compression = #EncoderValueCompressionCCITT3
;        compression = #EncoderValueCompressionCCITT4
;        compression = #EncoderValueCompressionRle
;        compression = #EncoderValueCompressionNone
      dpi = 150
      Debug SaveTIFF(hImage, TIFFFile$, compression, dpi)
      GdiEnd()
    EndIf
  EndIf
EndIf

DataSection
EncoderCompression:
Data.l $e09d739d
Data.w $ccd4, $44ee
Data.b $8e, $ba, $3f, $bf, $8b, $e4, $fc, $58
EndDataSection
Regards,
El_Choni
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post by Kale »

OMFG! 8O Way Cool El_Choni! Your code works perfectly! Very Nice! 8O :D

Now i just need to find a way to find the image boundry on 1bit tiffs for cropping, then my utility is complete! I knew i'd have to dig out the tiff specs somewhere along the way! :?

Thanks for your code El_Choni.
--Kale

Image
Manolo
User
User
Posts: 75
Joined: Fri Apr 25, 2003 7:06 pm
Location: Spain

Post by Manolo »

El_Choni is one rock (and roll??? :twisted: )

Manolo
Return to the forum
El_Choni
TailBite Expert
TailBite Expert
Posts: 1007
Joined: Fri Apr 25, 2003 6:09 pm
Location: Spain

Post by El_Choni »

Why don't you just open them, crop the image and save them? Unless, for some odd reason, you need to keep the bit depth...

Regards,

PD: ¿qué tal, Manolo? ;)
El_Choni
Team100
New User
New User
Posts: 4
Joined: Fri Feb 18, 2005 10:28 pm

Post by Team100 »

I have tried this great code and it is working very well,
but only with compression = #EncoderValueCompressionLZW

not with the others. There is a message coming:
GdipSaveImageToFile() failed. Invalid parameter

I would need CCITT3 or CCITT4 for a fax project, but I am sorry, I could
not find the answer out of the GDI-Documentation :(
that meens I didnt find any constants there .... :?

Thank You for help

Team100
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

On a side note, with Photoshop CS, if I save a png or even a bmp format with different dpis, the file size grows with the dpi number. Maybe a file format issue though ... :) Plus, the higher the dpi the better it looks when printed, but I guess we already covered that 8)
Kale
PureBasic Expert
PureBasic Expert
Posts: 3000
Joined: Fri Apr 25, 2003 6:03 pm
Location: Lincoln, UK
Contact:

Post by Kale »

Shannara wrote:On a side note, with Photoshop CS, if I save a png or even a bmp format with different dpis, the file size grows with the dpi number. Maybe a file format issue though ... :) Plus, the higher the dpi the better it looks when printed, but I guess we already covered that 8)
This is one thing about images that many people have trouble understanding. Dots (pixels) per inch (DPI) doesn't necessarily dictate file size and vice versa.

You can increase an images DPI and not have it grow in file size at all if you choose to not resample the image during conversion. In fact its better to never resample an image if you want to increase its DPI because you can never add pixels that weren't there in the first place, i mean the software can have a guess and interpolate the pixels to give the immpression of a high resolution but that usually makes the images a bit blurry.

Images can of course be resampled to a lower resolution perfectly because you are simply removing pixels.

The physical image size (dimensions) and resolution must always be taken into account when determining file size, for example an image 1 metre square at a low resolution can be the same file size as an image 1 centimetre square at a high resolution.

http://en.wikipedia.org/wiki/Dots_per_inch
Last edited by Kale on Wed Aug 10, 2005 9:44 pm, edited 1 time in total.
--Kale

Image
Shannara
Addict
Addict
Posts: 1808
Joined: Thu Oct 30, 2003 11:19 pm
Location: Emerald Cove, Unformed

Post by Shannara »

Thanks for the explaination and the link :)
techjunkie
Addict
Addict
Posts: 1126
Joined: Wed Oct 15, 2003 12:40 am
Location: Sweden
Contact:

Post by techjunkie »

Kale wrote:because you can never add pixels that weren't there in the first place, i mean the software can have a guess and interpolate the pixels to give the immpression of a high resolution but that usually makes the images a bit blurry.
Yeah - that's true... if you don't use plugins like Ultrafractal, Fractint or Genuine Fractals; they do a amazing work when you want more resolution.
Image
(\__/)
(='.'=) This is Bunny. Copy and paste Bunny into your
(")_(") signature to help him gain world domination.
r_hyde
Enthusiast
Enthusiast
Posts: 155
Joined: Wed Jul 05, 2006 12:40 am

Post by r_hyde »

Any chance of El_Choni's excellent code being converted to PB4? I have made an attempt at it, but really to no avail. The source of my trouble in accomplishing it centers on line 191:

Code: Select all

If CompareMemory(*pImageCodecInfo\MimeType, *FormatW, 1, FormatWSize) 
*pImageCodecInfo\MimeType is a string, which CompareMemory() doesn't like. Can't use CompareMemoryString(), but *FormatW is not a string. I really haven't developed enough of an understanding of the code to figure out a workaround.

Anyone want to help?

TIA,
RH
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post by Trond »

If CompareMemory(@*pImageCodecInfo\MimeType, *FormatW, 1, FormatWSize)
r_hyde
Enthusiast
Enthusiast
Posts: 155
Joined: Wed Jul 05, 2006 12:40 am

Post by r_hyde »

Thanks, Trond! I guess that worked, 'cause now I've passed through to a new error. This one's mysterious - invalid memory access at line 184:

Code: Select all

CallFunctionFast(*GdipGetImageEncodersSize, @num, @size)
Mysterious, I say, because I've used this function successfully before, and I don't see why it would fail here. The only time I've seen it fail like that is when gdi+ has not been initialized, but in this case it certainly has been. I haven't spent much time yet troubleshooting it, but I hope I will be able to fix it!
Post Reply