TGA images

Is it possible to load a TGA image into a canvas?
My guessing is I will need a plugin of some description.
Its just needs to be a small preview also work on Windows and Mac

Einhugur software has a plugin for images. See http://einhugur.com/Html/Libs.html . But I didn’t see anything about TGA.

The MBS plugin has everything. A bit of Googling tells me that the ImageMagick plugin supports TGA. See https://www.monkeybreadsoftware.net/plugins-mbsimagemagickplugin.shtml .

Thanks Beatrix :slight_smile:

Hi Nige,

Here is a pictureFromTGA method a wrote a while back. If I remember correctly it isn’t 100% feature complete, but should work in most instances. Simply load your TGA data into a MemoryBlock, and then call the method to convert it to a Xojo Picture object.

Private Function pictureFromTGA(tgaData As MemoryBlock) As Picture
  ' www.Xojo3D.com
  ' X3 is a {Zoclee} initiative.
  
  Dim dataPtr As Ptr
  Dim dataPos As Integer
  Dim p As Picture
  Dim rgbMain As RGBSurface
  Dim rgbMask As RGBSurface
  Dim pixelCount As Integer
  Dim i As Integer
  Dim x As Integer
  Dim y As Integer
  Dim maskByte As Byte
  Dim yStep As Integer
  
  ' tga header information
  
  Dim ImageIDLen As Byte
  Dim ColorMap As Byte
  Dim ImageType As Byte
  Dim ColorMapOrigin As UInt16
  Dim ColorMapLen As UInt16
  Dim ColorMapEntrySize As Byte
  Dim ImageXOrigin As UInt16
  Dim ImageYOrigin As UInt16
  Dim ImageWidth As Integer
  Dim ImageHeight As Integer
  Dim ImagePixelSize As Byte
  Dim ImageDescriptor As Byte
  
  dataPtr = tgaData
  
  ImageIDLen = dataPtr.Byte(0)
  ColorMap = dataPtr.Byte(1)
  ImageType = dataPtr.Byte(2)
  ColorMapOrigin = dataPtr.UInt16(3)
  ColorMapLen = dataPtr.UInt16(5)
  ColorMapEntrySize = dataPtr.Byte(7)
  
  ImageXOrigin = dataPtr.UInt16(8)
  ImageYOrigin = dataPtr.UInt16(10)
  ImageWidth = dataPtr.UInt16(12)
  ImageHeight = dataPtr.UInt16(14)
  ImagePixelSize = dataPtr.Byte(16)
  ImageDescriptor = dataPtr.Byte(17)
  
  p = new Picture(ImageWidth, ImageHeight, 32)
  rgbMain = p.RGBSurface
  rgbMask = p.Mask.RGBSurface
  
  select case ImageType
    
  case 2 ' ***** Unmapped RGB images ***************************
    
    dataPos = 18 + ImageIDLen + ColorMapLen
    
    pixelCount = ImageWidth * ImageHeight
    x = 0
    if (ImageDescriptor and 32) > 0 then
      y = 0
      yStep = 1
    else
      y = ImageHeight - 1
      yStep = -1
    end if
    
    select case ImagePixelSize
      
    case 24
      
      i = 0
      while i < pixelCount
        
        rgbMain.Pixel(x, y) = RGB(dataPtr.Byte(dataPos + 2), dataPtr.Byte(dataPos + 1), dataPtr.Byte(dataPos))
        rgbMask.Pixel(x, y) = RGB(maskByte, maskByte, 0)
        
        dataPos = dataPos + 3
        x = x + 1
        if x >= ImageWidth then
          x = 0
          y = y + yStep
        end if
        
        i = i + 1
      wend
      
    case 32
      
      i = 0
      while i < pixelCount
        
        rgbMain.Pixel(x, y) = RGB(dataPtr.Byte(dataPos + 2), dataPtr.Byte(dataPos + 1), dataPtr.Byte(dataPos))
        maskByte = 255 - dataPtr.Byte(dataPos + 3)
        rgbMask.Pixel(x, y) = RGB(maskByte, maskByte, maskByte)
        
        dataPos = dataPos + 4
        x = x + 1
        if x >= ImageWidth then
          x = 0
          y = y + yStep
        end if
        
        i = i + 1
      wend
      
    end select
    
  end select
  
  return p
End Function

Thanks Alwyn - some comments on that code:

  p = new Picture(ImageWidth, ImageHeight, 32)

This will make an old-style picture object (which has a picture with a separate mask). Depending on the use, the new-style picture might be more useful here:

  p = new Picture(ImageWidth, ImageHeight)

if you do that, then there is no need for RGBMask and you can just assign all 4 values (R,G,B,Alpha) to the image itself.

        rgbMain.Pixel(x, y) = RGB(dataPtr.Byte(dataPos + 2), dataPtr.Byte(dataPos + 1), dataPtr.Byte(dataPos), maskByte)

Speeding up the code - you may want to add this to the first line:

#pragma DisableBackgroundTasks 

Thank you for the optimization tips Michael.

Putting it to 32 bit though puts you in the pre-multiplied alpha situation though, which is fine for just painting the picture, but if you want to further process it then its really a no go.

This sounds interesting Björn. Out of curiosity, what other processing besides painting the picture can one do with TGA?

Thank you! I’ll give it a try today

This is a c# test, basically its a simple tool to load a bunch of images by the prefix created by various texture map software, ShaderMap Pro creates tga’s for normal maps
It doesn’t matter if the images are downgraded as they are never saved, the tool just creates and xml file that the renderer can read :slight_smile:

You can do any kind of image processing, like some are doing, brighten, darken, any effect similar to what photoshop and other image applications would do.

Here is why premultiplied alpha channel is not suitable for image processing:

http://www.einhugur.com/Html/infos/premultiplied.html