예제 #1
0
파일: emf.c 프로젝트: edalquist/ImageMagick
static Image *ReadEMFImage(const ImageInfo *image_info,
  ExceptionInfo *exception)
{
  Gdiplus::Bitmap
    *bitmap;

  Gdiplus::BitmapData
     bitmap_data;

  Gdiplus::GdiplusStartupInput
    startup_input;

  Gdiplus::Graphics
    *graphics;

  Gdiplus::Image
    *source;

  Gdiplus::Rect
    rect;

  GeometryInfo
    geometry_info;

  Image
    *image;

  MagickStatusType
    flags;

  register Quantum
    *q;

  register ssize_t
    x;

  ssize_t
    y;

  ULONG_PTR
    token;

  unsigned char
    *p;

  wchar_t
    fileName[MagickPathExtent];

  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);

  image=AcquireImage(image_info,exception);
  if (Gdiplus::GdiplusStartup(&token,&startup_input,NULL) != 
    Gdiplus::Status::Ok)
    ThrowReaderException(CoderError, "GdiplusStartupFailed");
  MultiByteToWideChar(CP_UTF8,0,image->filename,-1,fileName,MagickPathExtent);
  source=Gdiplus::Image::FromFile(fileName);
  if (source == (Gdiplus::Image *) NULL)
    {
      Gdiplus::GdiplusShutdown(token);
      ThrowReaderException(FileOpenError,"UnableToOpenFile");
    }

  image->resolution.x=source->GetHorizontalResolution();
  image->resolution.y=source->GetVerticalResolution();
  image->columns=(size_t) source->GetWidth();
  image->rows=(size_t) source->GetHeight();
  if (image_info->density != (char *) NULL)
    {
      flags=ParseGeometry(image_info->density,&geometry_info);
      image->resolution.x=geometry_info.rho;
      image->resolution.y=geometry_info.sigma;
      if ((flags & SigmaValue) == 0)
        image->resolution.y=image->resolution.x;
      if ((image->resolution.x > 0.0) && (image->resolution.y > 0.0))
        {
          image->columns=(size_t) floor((Gdiplus::REAL) source->GetWidth() /
            source->GetHorizontalResolution() * image->resolution.x + 0.5);
          image->rows=(size_t)floor((Gdiplus::REAL) source->GetHeight() /
            source->GetVerticalResolution() * image->resolution.y + 0.5);
        }
    }

  bitmap=new Gdiplus::Bitmap((INT) image->columns,(INT) image->rows,
    PixelFormat32bppARGB);
  graphics=Gdiplus::Graphics::FromImage(bitmap);
  graphics->SetInterpolationMode(Gdiplus::InterpolationModeHighQualityBicubic);
  graphics->SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
  graphics->SetTextRenderingHint(Gdiplus::TextRenderingHintClearTypeGridFit);
  graphics->Clear(Gdiplus::Color((BYTE) ScaleQuantumToChar(
    image->background_color.alpha),(BYTE) ScaleQuantumToChar(
    image->background_color.red),(BYTE) ScaleQuantumToChar(
    image->background_color.green),(BYTE) ScaleQuantumToChar(
    image->background_color.blue)));
  graphics->DrawImage(source,0,0,(INT) image->columns,(INT) image->rows);
  delete graphics;
  delete source;

  rect=Gdiplus::Rect(0,0,(INT) image->columns,(INT) image->rows);
  if (bitmap->LockBits(&rect,Gdiplus::ImageLockModeRead,PixelFormat32bppARGB,
    &bitmap_data) != Gdiplus::Ok)
  {
    delete bitmap;
    Gdiplus::GdiplusShutdown(token);
    ThrowReaderException(FileOpenError,"UnableToReadImageData");
  }

  image->alpha_trait=BlendPixelTrait;
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    p=(unsigned char *) bitmap_data.Scan0+(y*abs(bitmap_data.Stride));
    if (bitmap_data.Stride < 0)
      q=GetAuthenticPixels(image,0,image->rows-y-1,image->columns,1,exception);
    else
      q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
    if (q == (Quantum *) NULL)
      break;

    for (x=0; x < (ssize_t) image->columns; x++)
    {
      SetPixelBlue(image,ScaleCharToQuantum(*p++),q);
      SetPixelGreen(image,ScaleCharToQuantum(*p++),q);
      SetPixelRed(image,ScaleCharToQuantum(*p++),q);
      SetPixelAlpha(image,ScaleCharToQuantum(*p++),q);
      q+=GetPixelChannels(image);
    }

    if (SyncAuthenticPixels(image,exception) == MagickFalse)
      break;
  }

  bitmap->UnlockBits(&bitmap_data);
  delete bitmap;
  Gdiplus::GdiplusShutdown(token);
  return(image);
}
예제 #2
0
파일: image.cpp 프로젝트: identity0815/os45
int DrawSdk::Image::WriteScaledImageFile(WCHAR* scaledImageName, float scaleX, float scaleY, const WCHAR* format)
{
   int hr = S_OK;
 
//   // Starting the Gdiplus machine should be executed outside of this method
//   Gdiplus::GdiplusStartupInput gdiplusStartupInput;
//   ULONG_PTR gdiplusToken;
//   Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

   Gdiplus::ImageCodecInfo *pImageCodecInfo = NULL;

   CLSID *pClsid = NULL;

   HDC hdc = CreateCompatibleDC(NULL);
   

   // Get the encoder CLSID depending on the image format (image/jpeg, image/gif, image/png)
   UINT num = 0;
   UINT size = 0;

   Gdiplus::GetImageEncodersSize(&num, &size);
   if (size == 0)
      hr = -1;  // Failure

   if (SUCCEEDED(hr))
   {
      pImageCodecInfo = (Gdiplus::ImageCodecInfo*)(malloc(size));
      if (pImageCodecInfo == NULL)
         hr = -1;  // Failure
   }

   if (SUCCEEDED(hr))
   {
      Gdiplus::GetImageEncoders(num, size, pImageCodecInfo);

      for(int j = 0; j < num; ++j)
      {
         if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
         {
            pClsid = &pImageCodecInfo[j].Clsid;
            break;  // Success
         }    
      }

      if (pClsid == NULL)
         hr = -1;  // Failure
   }

   // Bugfix 5301: 
   // If 'gdipImage_' is NULL then it was not kept in memory and therefore 
   // a temporary Gdiplus::Image object is created for the rescaling. 
   // This avoids having too much image data in the memory.
   Gdiplus::Image *tmpImage = NULL;
   if (SUCCEEDED(hr) && gdipImage_ == NULL) {
       // convert char-String in WCHAR-String  
       int iStringLength = _tcslen(imageName_) + 1;
       WCHAR *wcFilename = (WCHAR *)malloc(iStringLength*sizeof(WCHAR));
#ifdef _UNICODE
       wcscpy(wcFilename, imageName_);
#else
       MultiByteToWideChar( CP_ACP, 0, imageName, iStringLength, 
           wcFilename, iStringLength);
#endif
       tmpImage = new Gdiplus::Image(wcFilename, FALSE);

       if (wcFilename)
           free(wcFilename);
   } else {
       tmpImage = gdipImage_;
   }


   if (SUCCEEDED(hr) && tmpImage != NULL)
   {
      // Resize the image by scaling factors
      Gdiplus::REAL destWidth  = scaleX * this->GetWidth();
      Gdiplus::REAL destHeight = scaleY * this->GetHeight();

      // If no correct size is defined in the object queue, use the real image size instead
      if ( (this->GetWidth() <= 0.0f) && (this->GetHeight() <= 0.0f) )
      {
         destWidth  = scaleX * tmpImage->GetWidth();
         destHeight = scaleY * tmpImage->GetHeight();
      }

      // At least we have to write one pixel
      if (destWidth < 1.0f)
         destWidth = 1.0f;
      if (destHeight < 1.0f)
         destHeight = 1.0f;

      Gdiplus::Bitmap scaledImage((int)(destWidth + 0.5f), (int)(destHeight + 0.5f));

      scaledImage.SetResolution(tmpImage->GetHorizontalResolution(), 
                                tmpImage->GetVerticalResolution());

      Gdiplus::Graphics grPhoto(&scaledImage);

      grPhoto.SetCompositingQuality(Gdiplus::CompositingQualityHighSpeed);
      grPhoto.SetCompositingMode(Gdiplus::CompositingModeSourceOver);
      grPhoto.SetInterpolationMode(Gdiplus::InterpolationModeHighQualityBicubic);

      Gdiplus::Rect destRect(0, 0, (int)(destWidth + 0.5f), (int)(destHeight + 0.5f));

      hr = grPhoto.DrawImage(tmpImage, destRect, 
                             0, 0, tmpImage->GetWidth(),tmpImage->GetHeight(), 
                             Gdiplus::UnitPixel);


      // Write the scaled image to a file
      if (SUCCEEDED(hr))
         hr = scaledImage.Save(scaledImageName, pClsid, NULL);
   }


   // Cleanup
   if (hdc)
	{
		::DeleteDC(hdc);
		hdc = NULL;
	}
   if (pImageCodecInfo)
   {
      free(pImageCodecInfo);
      pImageCodecInfo = NULL;
   }

   if (tmpImage != NULL && tmpImage != gdipImage_)
       delete tmpImage;

   
//   // Stop the Gdiplus machine --> this should be executed outside of this method (see above)
//   Gdiplus::GdiplusShutdown(gdiplusToken);

   return hr;
}