15 using namespace Gdiplus;
16 #pragma comment (lib,"Gdiplus.lib") 49 const KKStr& imageFileName
53 const KKStr& imageFileName
57 const KKStr& imageFileName
74 atexit (ImageIoFinaleCleanUp);
85 for (row = 0; row < image
.Height (); row++)
87 for (col = 0; col < image
.Width (); col++)
89 cout << image.GetPixelValue ( row, col) <<
" ";
110 RasterPtr KKB::ReadImage (
const KKStr& imageFileName)
114 CImg<
short> img = imageFileName.Str ();
118 if (img.dimv () == 1)
123 RasterPtr image =
new Raster (img.dimy (), img.dimx ());
128 for (row = 0; row < img.dimy(); row++)
130 for (col = 0; col < img.dimx(); col++)
134 r = *img.ptr (col, row, 0, 0);
135 g = *img.ptr (col, row, 0, 1);
136 b = *img.ptr (col, row, 0, 2);
138 grayValue = (kkint32)((
float)r * (
float)0.30 +
139 (
float)g * (
float)0.59 +
140 (
float)b * (
float)0.11 +
144 image->SetPixelValue (row, col, grayValue);
148 image->SetPixelValue (row, col, *img.ptr (col, row, 0, 0));
153 image->FileName (imageFileName);
160 void KKB::SaveImage (
const Raster& image,
161 const KKStr& imageFileName
166 CImg<
short> img (image.Width (), image.Height (), 1, 1);
168 for (row = 0; row < image.Height (); row++)
170 for (col = 0; col < image.Width (); col++)
172 img.data[img.offset (col, row, 0, 0)] = image.GetPixelValue (row, col);
176 img.save_other (imageFileName.Str ());
190 bool successful =
false;
191 RasterPtr image = NULL;
194 if (extension
== "pgm")
199 else if (extension
== "bmp")
207 else if (extension
== "ppm")
213 else if ((extension
== "jpg") || (extension
== "tif") || (extension
== "tiff"))
230 #include <Gdipluspixelformats.h> 241 GdiplusStartupInput gdiplusStartupInput;
242 ULONG_PTR gdiplusToken;
244 GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
253 wchar_t* imageFileNameWide = imageFileName
.ToWchar_t ();
255 Bitmap* bm = Bitmap::FromFile (imageFileNameWide,
false);
258 cerr << endl <<
"KKB::ReadImageUsingGDI ***ERROR*** Reading file: " << imageFileName << endl;
262 kkuint32 height = bm->GetHeight ();
263 kkuint32 width = bm->GetWidth ();
265 BitmapData* bitmapData =
new BitmapData ();
266 Gdiplus::Rect rect (0, 0, width, height);
268 bm->LockBits(&rect, Gdiplus::ImageLockModeRead, bm->GetPixelFormat (), bitmapData);
270 Gdiplus::PixelFormat pixFormat = bitmapData->PixelFormat;
271 kkint32 stride = bitmapData->Stride;
272 void* scan0 = bitmapData->Scan0;
274 if (pixFormat == PixelFormat24bppRGB)
276 r =
new Raster (height, width,
true);
278 kkint32 nOffset = stride - width * 3;
279 kkint32 bytesPerRow = width * 3 + nOffset;
287 bool grayScaleImage =
true;
289 uchar* ptr = (uchar*)(
void*)scan0;
290 for (row = 0; row < height; ++row)
292 for (col = 0; col < width; ++col)
297 r->SetPixelValue (row, col, red, green, blue);
299 if ((red != green) || (red != blue))
300 grayScaleImage=
false;
307 RasterPtr grayScaleR = r->CreateGrayScale ();
314 else if (pixFormat == PixelFormat8bppIndexed)
316 kkint32 paletteSize = bm->GetPaletteSize ();
318 ColorPalette* palette = (ColorPalette*)malloc (paletteSize);
319 bm->GetPalette (palette, paletteSize);
321 INT paletteHasAlpha = palette->Flags & PaletteFlagsHasAlpha;
322 INT paletteHasGrayScale = palette->Flags & PaletteFlagsGrayScale;
323 INT paletteHasHalftone = palette->Flags & PaletteFlagsHalftone;
325 r =
new Raster (height, width,
false);
326 kkint32 nOffset = stride - width;
327 kkint32 bytesPerRow = width + nOffset;
333 uchar* ptr = (uchar*)(
void*)scan0;
335 for (row = 0; row < height; ++row)
337 for (col = 0; col < width; ++col)
341 ARGB argb = palette->Entries[index];
343 kkint32 grayScaleValue = argb % 256;
345 r->SetPixelValue (row, col, (uchar)grayScaleValue);
355 bm->UnlockBits (bitmapData);
357 delete bitmapData; bitmapData = NULL;
358 delete bm; bm = NULL;
361 delete imageFileNameWide;
362 imageFileNameWide = NULL;
398 if (headerFieldsRead == 0)
403 if (headerFieldsRead == 1)
414 if ((pixelSize < 0) || (pixelSize > 255) ||
415 (width < 1) || (height < 1)
420 <<
"ReadImagePGM ***ERROR*** ImageFile[" << imageFileName <<
"] Invalid Header" 421 <<
" width[" << width <<
"] height[" << height <<
"] pixelSize[" << pixelSize <<
"]" 427 RasterPtr image =
new Raster (height
, width
, false);
433 for (row = 0; row < height; row++)
435 fread (colBuff, 1, width, i);
437 for (col = 0; col < width; col++)
457 kkint32 maxTokenLen =
sizeof (token) - 1;
461 bool startOfTokenFound =
false;
462 while (!startOfTokenFound)
465 ch = fgetc (in); eof = (feof (in) != 0);
466 while ((!eof) && (strchr (
" #\t\n\r", ch) != NULL) && (ch !=
'\n') && (ch !=
'#'))
467 {ch = fgetc (in); eof = (feof (in)!= 0);}
475 while ((!eof) && (ch !=
'\n'))
476 {ch = fgetc (in); eof = (feof (in)!= 0);}
481 startOfTokenFound =
true;
488 while ((!eof) && (strchr (
" #\t\n\r", ch) == 0))
490 token[tokenLen] = ch;
492 if (tokenLen >= maxTokenLen)
494 ch = fgetc (in); eof = (feof (in)!= 0);
497 if ((!eof) && (ch ==
'#'))
500 while ((!eof) && (ch !=
'\n'))
501 {ch = fgetc (in); eof = (feof (in)!= 0);}
504 if (eof & (tokenLen > 0))
528 kkint32 bytesRead = (kkint32)fread (buff, 1, 2, i);
535 bool p3Format = ((buff[0] ==
'P') && (buff[1] ==
'3'));
536 bool p6Format = ((buff[0] ==
'P') && (buff[1] ==
'6'));
538 if (!p3Format && !p6Format)
546 while ((fieldNum < 3) && (!eof))
558 if ((width < 1) || (height < 1) || (pixelDepth < 1) || (pixelDepth > 65535))
560 cerr << endl <<
"ReadImagePPM ***ERROR*** Invalid Header Fields: " 561 <<
"FileName[" << imageFileName <<
"] " 562 <<
"Width[" << width <<
"] Height[" << height <<
"] PixelDepth[" << pixelDepth <<
"]" 569 RasterPtr image =
new Raster (height
, width
, true);
570 int totalPixels = height * width;
579 while ((pixelsRead < totalPixels) && (!eof))
585 kkint32 redValue = Min (redField.ToInt32 (), pixelDepth);
586 kkint32 greenValue = Min (greenField.ToInt32 (), pixelDepth);
587 kkint32 blueValue = Min (blueField.ToInt32 (), pixelDepth);
589 *red = ((255 * redValue) / pixelDepth); ++red;
590 *green = ((255 * greenValue) / pixelDepth); ++green;
591 *blue = ((255 * blueValue) / pixelDepth); ++blue;
599 while ((pixelsRead < totalPixels) && (!eof))
601 fread (rgbBuff, 1, 3, i); eof = (feof (i) != 0);
602 *red = rgbBuff[0]; ++red;
603 *green = rgbBuff[1]; ++green;
604 *blue = rgbBuff[2]; ++blue;
618 const KKStr& imageFileName
624 if (extension
== "BMP")
631 catch (
const KKStr& errMsg)
637 KKStr msg =
"SaveImage Exception Saving image using 'BmpImage'";
638 cerr << std::endl << msg << std::endl << std::endl;
643 KKStr errMsg =
"SaveImage Exception occurred calling 'BmpImage::Save' for file[" + imageFileName
+ "]";
644 cerr << std::endl << errMsg << std::endl << std::endl;
649 else if (extension
== "PGM")
654 else if (extension
== "PNG")
661 KKStr errMsg =
"ImageIO::SaveImage Extension[" + extension
+ "] is not supported.";
663 cerr << std::endl << std::endl << std::endl
664 <<
"SaveImage *** ERROR *** " << std::endl
665 << errMsg << std::endl
676 const KKStr& imageFileName
683 headerStr <<
"P5" << endl
684 << image.Width () << endl
685 << image.Height () << endl
686 << (kkint16)255 << endl;
688 const char* h = headerStr
.Str ();
689 fwrite (h, 1, headerStr.Len (), o);
698 fwrite (g, 1, totalPixels, o);
699 delete grayScaleImage;
704 fwrite (g, 1, totalPixels, o);
713 const KKStr& imageFileName
719 KKStr errMsg =
"SaveImagePNG Error opening File[" + imageFileName
+ "]";
720 cerr << std::endl << errMsg << std::endl << std::endl;
726 headerStr <<
"P6" << endl
727 << image.Width () << endl
728 << image.Height () << endl
729 << (kkint16)255 << endl;
731 const char* h = headerStr
.Str ();
732 fwrite (h, 1, headerStr.Len (), o);
743 for (
kkint32 x = 0; x < totalPixels; x++)
745 fwrite (red, 1, 1, o); ++red;
746 fwrite (green, 1, 1, o); ++green;
747 fwrite (blue, 1, 1, o); ++blue;
755 for (
kkint32 x = 0; x < totalPixels; x++)
757 uchar intensity = 255 - (*green);
758 buff3[0] = intensity;
759 buff3[1] = intensity;
760 buff3[2] = intensity;
761 fwrite (buff3, 1, 3, o);
775 const KKStr& imageFileName
781 KKStr errMsg =
"SaveImagePNG Error opening File[" + imageFileName
+ "]";
782 cerr << std::endl << errMsg << std::endl << std::endl;
788 headerStr <<
"P6" << endl
789 << image.Width () << endl
790 << image.Height () << endl
791 << (kkint16)255 << endl;
793 const char* h = headerStr
.Str ();
794 fwrite (h, 1, headerStr.Len (), o);
805 for (
kkint32 x = 0; x < totalPixels; x++)
807 fwrite (red, 1, 1, o); ++red;
808 fwrite (green, 1, 1, o); ++green;
809 fwrite (blue, 1, 1, o); ++blue;
817 for (
kkint32 x = 0; x < totalPixels; x++)
819 uchar intensity = *green;
820 buff3[0] = intensity;
821 buff3[1] = intensity;
822 buff3[2] = intensity;
823 fwrite (buff3, 1, 3, o);
842 const KKStr& imageFileName
845 RasterPtr invertedImage =
new Raster (raster
);
853 for (r = 0; r < invertedImage
->Height (); r++)
855 for (c = 0; c < invertedImage
->Width (); c++)
857 g[r][c] = 255 - g[r][c];
860 red [r][c] = 255 - red [r][c];
861 blue[r][c] = 255 - blue[r][c];
867 delete invertedImage;
868 invertedImage = NULL;
875 const KKStr& _fileName
882 msg <<
"KKB::SaveImageGrayscaleInverted4Bit Only 'BMP' files are supported; FileName[" << _fileName <<
"].";
883 cerr << endl <<
"***ERROR*** " << msg << endl << endl;
894 KKStr msg =
"SaveImageGrayscaleInverted4Bit Exception Saving image using 'BmpImage' for file[" + _fileName
+ "]";
895 cerr << std::endl << msg << std::endl << std::endl;
900 KKStr errMsg =
"SaveImageGrayscaleInverted4Bit Exception occurred calling 'BmpImage::Save' for file[" + _fileName
+ "]";
901 cerr << std::endl << errMsg << std::endl << std::endl;
915 const KKStr& _fileName
922 msg <<
"KKB::SaveImageGrayscaleInverted4Bit Only 'BMP' files are supported; FileName[" << _fileName <<
"].";
923 cerr << endl <<
"***ERROR*** " << msg << endl << endl;
934 KKStr msg =
"SaveImageGrayscaleInverted8Bit Exception Saving image using 'BmpImage'";
935 cerr << std::endl <<
"***ERROR*** " << msg << std::endl << std::endl;
940 KKStr errMsg =
"SaveImageGrayscaleInverted8Bit Exception occurred calling 'BmpImage::Save' for file[" + _fileName
+ "]";
941 cerr << std::endl << errMsg << std::endl << std::endl;
967 GdiplusShutdown(gdiplusToken);
KKStr(kkint32 size)
Creates a KKStr object that pre-allocates space for 'size' characters.
char operator[](kkint16 i) const
RasterPtr ReadImagePPM(const KKStr &imageFileName)
KKStr ReadImagePpmField(FILE *in, bool &eof)
bool EqualIgnoreCase(const char *s2) const
wchar_t * ToWchar_t() const
KKException(const KKStr &_exceptionStr, const KKException &_innerException)
RasterPtr ReadImagePGM(const KKStr &imageFileName)
void SetPixelValue(kkint32 row, kkint32 col, uchar pixVal)
RasterPtr ReadImageUsingGDI(const KKStr &imageFileName)
A class that is used by to represent a single image in memory.
bool operator==(const char *rtStr) const
void SaveGrayscaleInverted8Bit(const KKStr &_fileName)
Saves image using compressed gray-scale where Background = 255 and foreground = 0.
void SaveImagePGM(const Raster &image, const KKStr &imageFileName)
KKStr operator+(const char *right) const
bool SupportedImageFileFormat(const KKStr &imageFileName)
void DefineImageIoAtExit()
KKStr osReadNextToken(FILE *in, const char *delimiters, bool &eof)
Read the next logical token from a file using characters in 'delimiters' to separate tokens where ' '...
RasterPtr ReadImage(const KKStr &imageFileName)
KKStr osGetFileExtension(KKStr fullFileName)
BmpImage(const Raster &raster)
Constructs a BMPImage instance from a Raster image; this is one way to save a Raster image to disk...
void ImageIoFinaleCleanUp()
KKStr & operator=(KKStr &&src)
void SaveImagePPM(const Raster &image, const KKStr &imageFileName)
KKB::KKStr osReadRestOfLine2(FILE *in, bool &eof)
void DisplayImage(const Raster &raster, const KKStr &title)
KKStr operator+(const char *left, const KKStr &right)
Used to encode and decode BMP Images.
void SaveImageGrayscaleInverted4Bit(const Raster &image, const KKStr &_fileName)
Saves image as BMP file using 4 bit compressed gray-scale where Background = 255 and foreground = 0...
void SaveGrayscaleInverted4Bit(const KKStr &_fileName)
Saves image using 4 bit compressed gray-scale where Background = 255 and foreground = 0...
GdiplusStartupInput gdiplusStartupInput
void SaveImage(const Raster &image, const KKStr &imageFileName)
void SaveImageGrayscaleInverted8Bit(const Raster &image, const KKStr &_fileName)
Saves image as BMP using compressed gray-scale where Background = 255 and foreground = 0...
void SaveImageInverted(Raster &raster, const KKStr &imageFileName)
unsigned char uchar
Unsigned character.
static KKStr Concat(const std::vector< std::string > &values)
Concatenates the list of 'std::string' strings.
void Upper()
Converts all characters in string to their Upper case equivalents via 'toupper'.
static const KKStr & EmptyStr()
Static method that returns an Empty String.
void Save(const KKStr &fileName)
Raster(kkint32 _height, kkint32 _width, bool _color)
Constructs a blank image with given dimensions.
kkint32 ExtractTokenInt(const char *delStr)
uchar * GreenArea() const
const char * Str() const
Returns a pointer to a ascii string.
FILE * osFOPEN(const char *fileName, const char *mode)
Raster(const BmpImage &_bmpImage)
Constructs a Raster from a BMP image loaded from disk.
Raster(const Raster &_raster)
Copy Constructor.
bool imageIoAtExitDefined
void DisplayImage(const Raster &image)
KKException(const KKStr &_exceptionStr)
RasterPtr CreateGrayScale() const
BmpImage(const KKStr &_fileName, bool &successful)
Constructs a BMP image from the file specified by '_fileName'.
void SaveImagePNG(const Raster &image, const KKStr &imageFileName)