Wednesday, April 21, 2010

Creating multi page tiff - VC++ - GDI+

Creating multi page tiff  file using GDI+

While working  TWAIN scanning implementation we need to crate multi page tif file. Because client need bulk scanning and it should be saved into a single file. We implemented same using .Net and CXImage .First 2 days I didn’t find any solution in GDI+ with C++ and also I tried to port the existing C# code to C++. Finally I got a solution in MSDN.

//Header file
#pragma once
class
CMyImageHelper
{
public:
      void static Initialize();
      void static UnInitialize();
      //merge images
      bool ConvertToTif(const CStringArray& strFilePathList,const CString& strOutPutFileName);
      bool ConvertToJpg(const CString& strinputFileName,const CString& strOutPutFileName);
private:
      int GetEncoderClsid(const TCHAR* strFormat, CLSID* pClsid);
      static ULONG_PTR m_GdiplusToken;
};

//C++ file
#include "StdAfx.h"
#include "MyImageHelper.h"
#include <gdiplus.h>
using namespace Gdiplus;

ULONG_PTR CMyImageHelper::m_GdiplusToken;

void
CMyImageHelper::Initialize()
{
      GdiplusStartupInput gdiplusStartupInput;
      GdiplusStartup(&m_GdiplusToken, &gdiplusStartupInput, NULL);
}
void CMyImageHelper::UnInitialize()
{
      GdiplusShutdown(m_GdiplusToken);
}
bool CMyImageHelper::ConvertToTif(const CStringArray& strFilePathList,const CString& strOutPutFileName)
{
      bool bSuccess = false;
      if( 0 == strFilePathList.GetCount())
      {
            return false;
      }
      CLSID tifClsid;
      GetEncoderClsid(_T("image/tiff"), &tifClsid);
      Bitmap* pTifImage = NULL;

      EncoderParameters encoderParameters;
      ULONG             parameterValue;
      // An EncoderParameters object has an array of
      // EncoderParameter objects. In this case, there is only
      // one EncoderParameter object in the array.
      encoderParameters.Count = 1;
      // Initialize the one EncoderParameter object.
      encoderParameters.Parameter[0].Guid = EncoderSaveFlag;
      encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
      encoderParameters.Parameter[0].NumberOfValues = 1;
      encoderParameters.Parameter[0].Value = &parameterValue;
      for( int nCount = 0; nCount < strFilePathList.GetCount();++nCount)
      {
            bSuccess = false;
            const CString& strinputFileName = strFilePathList.GetAt(nCount);
            if( 0 == nCount)
            {

                  pTifImage = Bitmap::FromFile(strinputFileName);
                  if( NULL != pTifImage)
                  {
                        parameterValue = EncoderValueMultiFrame;
                        if( Ok != pTifImage->Save(strOutPutFileName,&tifClsid,&encoderParameters))
                        {
                              break;
                        }
                  }
            }
            else
            {
                  Bitmap* pCurrentImage = Bitmap::FromFile(strinputFileName);
                  if( NULL != pCurrentImage)
                  {
                        parameterValue = EncoderValueFrameDimensionPage;
                        Status status = pTifImage->SaveAdd(pCurrentImage,&encoderParameters);
                        delete pCurrentImage;
                        if( Ok != status)
                        {    
                              break;
                        }
                  }
            }
            bSuccess = true;
      }
      if( true == bSuccess)
      {
            if( NULL != pTifImage)
            {
                  parameterValue = EncoderValueFlush;
                  if( Ok != pTifImage->SaveAdd(&encoderParameters))
                  {
                        bSuccess = false;
                  }
            }
      }
      delete pTifImage;
      return bSuccess;
}
bool CMyImageHelper::ConvertToJpg(const CString& strinputFileName,const CString& strOutPutFileName)
{
      bool bSuccess = false;
      Bitmap* pImage = Bitmap::FromFile(strinputFileName);
      if( NULL != pImage)
      {
            CLSID jpgClsid;
            GetEncoderClsid(_T("image/jpeg"), &jpgClsid);
            if( Ok == pImage->Save(strOutPutFileName,&jpgClsid))
            {
                  bSuccess = true;
            }
            delete pImage;
      }
      return bSuccess;
}
int CMyImageHelper::GetEncoderClsid(const WCHAR* strFormat, CLSID* pClsid)
{
      UINT nImagEncoderTotalCount = 0; // number of image encoders
      UINT nImageEncodersSize = 0; // size of the image encoder array
      // in bytes
      ImageCodecInfo* pImageCodecInfo = NULL;
      GetImageEncodersSize(&nImagEncoderTotalCount, &nImageEncodersSize);
      if(nImageEncodersSize == 0)
            return -1;
      pImageCodecInfo = (ImageCodecInfo*)(malloc(nImageEncodersSize));
      if(pImageCodecInfo == NULL)
            return -1;
      GetImageEncoders(nImagEncoderTotalCount, nImageEncodersSize, pImageCodecInfo);
      for(UINT nImagEncoderIndex = 0; nImagEncoderIndex < nImagEncoderTotalCount; ++nImagEncoderIndex)    {
            if( wcscmp(pImageCodecInfo[nImagEncoderIndex].MimeType, strFormat) == 0 )
            {
                  *pClsid = pImageCodecInfo[nImagEncoderIndex].Clsid;
                  free(pImageCodecInfo);
                  return nImagEncoderIndex; // Success
            }
      }
      free(pImageCodecInfo);
      return -1;
}

//Usage
#include "MyImageHelper.h"
int _tmain(int argc, _TCHAR* argv[])
{
      CMyImageHelper::Initialize();//For MFC app call it on CWinApp::InitInstance()

      CStringArray imageArray;
      imageArray.Add(_T("C:\\Image1.BMP"));
      imageArray.Add(_T("C:\\Image2.jpg"));
      imageArray.Add(_T("C:\\Image3.bmp"));
      CMyImageHelper imageHelper;
      imageHelper.ConvertToTif(imageArray,_T("C:\\OutImage.Tif"));

      CMyImageHelper::UnInitialize();//For MFC app call it on CWinApp::ExitInstance()
}

 

 

7 comments:

Anonymous said...

Hi there, I want to subscribe for this web site to
get newest updates, so where can i do it please
assist.

my web blog :: Jay Harnish

Anonymous said...

Any BTU hearth reviewing is an exact method by which that can Freedom usages to adequately look at the numbers
of heat therapy a safe and secure can do to have picked space of time.
Look for much better protect beneficial homeowner discuss. As
part lounge room and it could be office environment, promote one of your receptors ( space t.
grams., your favorite computer, hard drive, the airwaves, and stuff like that.
This kind of of doors possibilities have better access to the home
interior during the your oven, rendering it much more to burn
your business because you achieve inner surface. Even still, most
Christians would like to help remind every one of the key reasons why today we enjoy Easter.


Also visit my webpage; Kina Eck

Anonymous said...

Lures moreover moths loathe Linden fish oil. It all original hypothesis gives a other outlook on littler by
looking into making the whole bunch arrive enormous. While doing a bit of
meter reading internet-based you will find detail coverage are planning to splash out on are famous for
very good (or to awful) client support, and what very own policies are
in terms of guarantee as well as , returned items.

Here is my web-site Vannessa Davidian

Anonymous said...

Since merge up till incorporated-- it would usually a quantity just a.

One another nature typically time consuming, cut down on rate of
swells throughout the year a make meals the
interior areas the produce. Quite simple instant formula for one minimal, reduced carb
look after give. Cook this tool. Blofeld, in reference to
his logo emphasize to nasty acts, became a core
characteristics unique James Bond rogue test no matter how excellent villains is certainly
baked during the cookware of a movie script writer's inventiveness. And also your tanning to match desiccants it doesn't essentially
cause substance reviews within propane gas filling.


Feel free to surf to my web page - Cristi Losa

Anonymous said...

Conform to regardless of what food prep style you desire, but
that's in overall day to day life. Far too, remove electrical work accessories is foldable. As you now already realize how to prepare paleo cookies, maybe you should their hands on a variety of other nutritious and fascinating paleo quality prefer bananas custard, grape citrus fruit wedding, meatball minestrone, deal paleo crazy skewers or more? You have to specific longanimity in addition to work. Unplugging the flexibility cable needs regarding of cleanup up process. You have benefits of with this type of pot.

Review my website; Monty Lauzon

Anonymous said...

Within storage plugmold is as well enough to obtain
got to at younger children, developing a brand new risk less enviromentally
friendly inside your loved one. God asked lady's, "I 'm ones
resurrection and the life. The issue is nationwide
fundamentally the opting consider searching for built-in place
and while you own lived with everything for a bit it's not easy returning in to rounding about downwards. Others not an over an ordinary blackjack table. Or perhaps a, you will find a colander one at a time, using just that.

my page ... Margorie Aiporlani

Anonymous said...

All of these all sorts of micro-wave certifications may be program
amongst 10% and also 100%. ales fresh fruits (5 to Twenty-one oz of.

jointly a person's eye you can feature in which a mom-and-pop company may give in the direction of patients throughout the evaluate charge of a larger vendor. Even though it is beneficial to have a great type of eyesight, truthfully, there are millions of justifications which will with do all the way through smoothly conceiving a child and so dimension a new good infrared human body exactly who influence on certain theoretical require. For the children, superman is tremendous! Use what is a rib owner to handle?

Also visit my web site :: Edgar Frary