Click here to Skip to main content
15,884,388 members
Articles / Desktop Programming / MFC
Article

Adobe Photoshop file loader template class

Rate me:
Please Sign up or sign in to vote.
4.50/5 (2 votes)
29 Jan 20022 min read 99.3K   672   16   15
A template class to making loading Adobe Photoshop files easier

Introduction

Here is a quick way to load color, alpha and selection channel data from an flattened* Adobe Photoshop image file.  

* If Photoshop's save file preference is set to maximize compatibility with older versions the file will contain a pre-composited version of the image will be saved along with the layers. ).

Example Use

typedef BPT::TPSDFileLoader<ExampleSurface> loader_type;

typedef loader_type::channel_collection_type::iterator channel_iterator;

loader_type psdLoader;

loader_type::channel_collection_type * pChannels = psdLoader.Load( pszFilename );

if ( pChannels ){

    int channelCount = pChannels->size();

    std::cout << "There are " << channelCount << "channels.\n" << std::endl;

    int channel = 1;

    for ( channel_iterator it = pChannels->begin(); it != pChannels->end(); it++ ) {

        ExampleSurface * pSurface = *it;

        if ( 1 == channel ) {
            std::cout << "Red ";
        } else if ( 2 == channel ) {
            std:cout << "Green ";
        } else if ( 3 == channel ) {
            std:cout << "Blue ";
        } else {
            std:cout << "Alpha ";
        }

        std::cout << "Channel " << channel << "of " << channelCount;
        std::cout << " Width " << pSurface->Width();
        std::cout << " Height " << pSurface->Height();
        std::cout << endl;

        ++channel;

    }

    psdLoader.Unload( pChannels );

}

The TPSDFileLoader template parameters

template<
    class CHANNEL_SURFACE
    ,class CHANNEL_COLLECTION = std::list<CHANNEL_SURFACE *>
    ,class INPUT_POLICY = TFileIO<>
    ,class SIZE_COLLECTION = std::vector<int>
>
class TPSDFileLoader { 

The default template parameters are reasonable defaults for use in a Win32 environment. However if you want to bring the code to a slightly different platform or you have specific storage needs you can override defaults with your types. If you are fine with the defaults, the CHANNEL_SURFACE is the only type you *must* specify. 

CHANNEL_SURFACE

The loader references only four methods ( Create(), Width(), Height() and Iterator() ) and one exposed type ( pixel_iterator ) from the CHANNEL_SURFACE type.  The interface is relatively small it should be easy to write an adaptor class for most bitmap representations.  Here is an example surface that conforms to the loader's CHANNEL_SURFACE use.

struct ExampleSurface {

    typedef BYTE pixel_type;
    typedef pixel_type * pixel_iterator;

    SIZE m_Size;
    pixel_iterator m_Storage;

    int Width() { return m_Size.cx; }
    int Height() { return m_Size.cy; }

    pixel_iterator Iterator( const int x, const int y ) {
        if ( !m_Storage ) return 0;
        return m_Storage + (y * m_Size.cx) + x;
    }

    void Destroy() {
        if ( m_Storage ) {
            delete [] m_Storage;
            m_Storage = 0;
        }
        m_Size.cx = m_Size.cy = 0;
    }

    bool Create( const int width, const int height ) {

        Destroy();

        m_Storage = new pixel_type [ width * height ];

        m_Size.cx = width; m_Size.cy = height;

        return (0 != m_Storage);
        
    }

    ~ExampleSurface() { Destroy(); }

    ExampleSurface() : m_Storage(0) { m_Size.cx = m_Size.cy = 0; }

};

CHANNEL_COLLECTION

CHANNEL_COLLECTION is the collection type that will be used to return the channel data. 

class CHANNEL_COLLECTION = std::list<CHANNEL_SURFACE *>

INPUT_POLICY

This policy class is used to provide low-level input capabilities; the default class is simply a wrapper around the fopen/fclose and related basic read methods. It has methods for reading 16 bit and 32 bit values stored in endian specific fashion.  In addition to providing the necessary read interface it also hides memory allocation/deallocation details when reading chunks of data into memory. 

struct ExampleInputPolicy {
    bool Open( const char * filename, const char * access );
    void Close();
    void Seek( const int pos, const int mode );
    int Read_Byte();
    int Read_m16();
    int Read_m32();
    BYTE * LoadData( const int nBytes );
    void UnloadData( BYTE * ptr );
};

SIZE_COLLECTION

Internally the size of each channel is temporarily cached to make the loader implementation simpler. 

class SIZECOLLECTION = std::vector<int>

STL

if you want to eliminate the dependency on the STL you can do so by specifying a different collection type for both the SIZE_COLLECTION and CHANNEL_COLLECTION.

Includes

If you plan on using the default implementation you will need to include the list, vector headers. 

#include <list>
#include <vector>

#include "psd_load_src.h"

Public Methods

Unload() destroys the returned channel collection.

void Unload( CHANNEL_COLLECTION * pLoadedData );

LoadFromAbstraction() is the low-level public method, it is used to read from the IO policy object passed.

template< class INPUT > CHANNEL_COLLECTION *
LoadFromAbstraction( INPUT & input, const int nLoadChannelCountMax = 0 );

Load() -- accepts a null terminated string and uses the INPUT_POLICY and LoadFromAbstraction() to load the channel data.

CHANNEL_COLLECTION *
Load( const char * filename, const int nLoadChannelCountMax = 0 );

Usage

It's common to need access to the individual channel data in an Adobe Photoshop file, so this template saves a lot of time and effort. 

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United States United States
Programming since 1984, mostly in c/c++ and assembly language when necessary.

Comments and Discussions

 
GeneralImageMagick Pin
Uwe Keim22-Jan-02 21:29
sitebuilderUwe Keim22-Jan-02 21:29 
GeneralImgSource Pin
Chris Losinger23-Jan-02 4:52
professionalChris Losinger23-Jan-02 4:52 
GeneralRe: ImgSource Pin
Oz Solomon23-Jan-02 6:54
Oz Solomon23-Jan-02 6:54 
GeneralRe: ImgSource Pin
Chris Losinger23-Jan-02 7:50
professionalChris Losinger23-Jan-02 7:50 
GeneralRe: ImgSource Pin
Brad P. Taylor23-Jan-02 8:14
Brad P. Taylor23-Jan-02 8:14 
GeneralRe: ImgSource Pin
Chris Losinger23-Jan-02 9:40
professionalChris Losinger23-Jan-02 9:40 
GeneralRe: ImgSource Pin
Brad P. Taylor23-Jan-02 12:20
Brad P. Taylor23-Jan-02 12:20 
GeneralRe: ImgSource Pin
Chris Losinger23-Jan-02 9:48
professionalChris Losinger23-Jan-02 9:48 
GeneralRe: ImgSource Pin
Brad P. Taylor23-Jan-02 12:26
Brad P. Taylor23-Jan-02 12:26 
GeneralRe: ImgSource Pin
30-Jan-02 21:18
suss30-Jan-02 21:18 
GeneralRe: ImgSource Pin
Swinefeaster30-Jun-02 0:11
Swinefeaster30-Jun-02 0:11 
GeneralRe: ImgSource Pin
Anonymous16-Jul-02 0:36
Anonymous16-Jul-02 0:36 
GeneralRe: ImgSource Pin
Chris Losinger16-Jul-02 3:56
professionalChris Losinger16-Jul-02 3:56 
GeneralRe: ImgSource Pin
Christian Graus16-Jul-02 11:05
protectorChristian Graus16-Jul-02 11:05 
GeneralRe: ImgSource [XPost] Pin
Jonas Beckeman28-Jul-05 9:39
Jonas Beckeman28-Jul-05 9:39 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.