|
|
i'm looking for a raw code that blur and sharpen image. this is great article. thanks
|
|
|
|
|
Hi,
I would like to save the modified image to 24 bit png file. Using the following code it always saved as 32 bit png. Did I miss anything? Any information is highly appreciated.
Bitmap* foo = Bitmap::FromHBITMAP(m_hBitmap, NULL);
CLSID pngClsid;
GetEncoderClsid(L"image/png", &pngClsid);
foo->Save(szPath, &pngClsid, NULL);
Thanks,
Shuling
|
|
|
|
|
I get error message when I try to compile this code. Maybe I didn't installed GDI+ properly, which I downloaded from this site. I have done everything described on the page Hints to get GDI+ running[^]
These are the error messages I get:
e:\dokumenti\sistemi za dig\sourceimageviewernewver\cimageprocess.h(45) : error C2146: syntax error : missing ';' before identifier 'm_gdiplusStartupInput'
e:\dokumenti\sistemi za dig\sourceimageviewernewver\cimageprocess.h(45) : error C2501: 'GdiplusStartupInput' : missing storage-class or type specifiers
e:\dokumenti\sistemi za dig\sourceimageviewernewver\cimageprocess.h(45) : error C2501: 'm_gdiplusStartupInput' : missing storage-class or type specifiers
e:\dokumenti\sistemi za dig\sourceimageviewernewver\cimageprocess.cpp(20) : error C2065: 'GdiplusStartup' : undeclared identifier
e:\dokumenti\sistemi za dig\sourceimageviewernewver\cimageprocess.cpp(20) : error C2065: 'm_gdiplusStartupInput' : undeclared identifier
e:\dokumenti\sistemi za dig\sourceimageviewernewver\cimageprocess.cpp(70) : error C2065: 'Image' : undeclared identifier
e:\dokumenti\sistemi za dig\sourceimageviewernewver\cimageprocess.cpp(70) : error C2146: syntax error : missing ';' before identifier 'image'
e:\dokumenti\sistemi za dig\sourceimageviewernewver\cimageprocess.cpp(70) : error C2065: 'image' : undeclared identifier
e:\dokumenti\sistemi za dig\sourceimageviewernewver\cimageprocess.cpp(72) : error C2228: left of '.GetWidth' must have class/struct/union type
e:\dokumenti\sistemi za dig\sourceimageviewernewver\cimageprocess.cpp(73) : error C2228: left of '.GetHeight' must have class/struct/union type
e:\dokumenti\sistemi za dig\sourceimageviewernewver\cimageprocess.cpp(78) : error C2065: 'Graphics' : undeclared identifier
e:\dokumenti\sistemi za dig\sourceimageviewernewver\cimageprocess.cpp(78) : error C2146: syntax error : missing ';' before identifier 'g'
e:\dokumenti\sistemi za dig\sourceimageviewernewver\cimageprocess.cpp(78) : error C2065: 'g' : undeclared identifier
e:\dokumenti\sistemi za dig\sourceimageviewernewver\cimageprocess.cpp(79) : error C2065: 'Rect' : undeclared identifier
e:\dokumenti\sistemi za dig\sourceimageviewernewver\cimageprocess.cpp(79) : error C2146: syntax error : missing ';' before identifier 'rect'
e:\dokumenti\sistemi za dig\sourceimageviewernewver\cimageprocess.cpp(79) : error C2065: 'rect' : undeclared identifier
e:\dokumenti\sistemi za dig\sourceimageviewernewver\cimageprocess.cpp(80) : error C2228: left of '.DrawImage' must have class/struct/union type
Can you help me?
Thanks in advance.
|
|
|
|
|
To include this code at the stdafx.h file.
#include <GdiPlus.h>
using namespace Gdiplus;
|
|
|
|
|
Great job! ...simple solution!
How do we achieve lighting effect on specific areas from a perspective angle?
Thanks,
modified on Wednesday, July 15, 2009 9:08 PM
|
|
|
|
|
dear bala,
im abdul from coimbatore. ur project is very much helpful for me.. i need one more favor. do u have some more algorithms like edge detection, threshloding, contrast etc., if u have please send it to me. it will be very much useful for me. my mail id is ak_from_cbe@yahoo.com
thanks in advance.
regards
AK...
|
|
|
|
|
hi
how can i apply the code for vb.net?
|
|
|
|
|
I have written code for VC++. I have no idea for .Net.
----------BAla--------------
|
|
|
|
|
Your code is covered in memcpy and the magic nr 4.
If you didnt know this, there actually is a variable of that size called a double word , long, or a 32 bit integer.
Instead of using a char* buffer which is a BYTE you should use a buffer of unsigned __int32 or unsigned long in VC++!
You can either use definition UINT32 or DWORD.
There is NO need to multiply by 4. And you should NOT use malloc, you should use new when you are coding in C++ which you are.
All memcpy should be removed!
Part of your black&white code looks like this :
<code>
buf = (char *) malloc(m_nWidth * 4 * m_nHeight);
bRes = GetDIBits(hMemDC, m_hBitmap, 0, m_nHeight, buf, &bi,
DIB_RGB_COLORS);
long nCount=0;
for (int i=0; i<m_nHeight; ++i)
{
for (int j=0; j<m_nWidth; ++j)
{
long lVal=0;
memcpy(&lVal, &buf[nCount], 4);
int b = GetRValue(lVal);
int g = GetGValue(lVal);
int r = GetBValue(lVal);
lVal = (r+g+b)/3;
lVal = RGB(lVal, lVal, lVal);
memcpy(&buf[nCount], &lVal, 4);
nCount+=4;
}
}
SetDIBits(hMemDC, m_hBitmap, 0, bRes, buf, &bi,
DIB_RGB_COLORS);
free(buf);
This is how it should have been implemented :
<code>
UINT32* buf = new UINT32[ m_nWidth * m_nHeight ];
int scanLines = GetDIBits( hMemDC , m_hBitmap, 0 , m_nHeight , buf, &bi , DIB_RGB_COLORS );
if ( scanLines > 0 )
{
UINT32 nCount = 0;
UINT32 pixels = scanLines * m_nWidth;
COLORREF col = 0;
BYTE avg = 0;
do
{
col = buf[ nCount ];
avg = GetBValue( col ) * 0.3 + GetGValue( col ) * 0.59 + GetRValue( col ) * 0.11;
buf[ nCount ] = RGB( avg , avg , avg );
nCount++;
}
while ( nCount < pixels );
scanLines = SetDIBits( hMemDC, m_hBitmap , 0 , scanLines , buf, &bi , DIB_RGB_COLORS );
ASSERT( scanLines > 0 );
}
else ASSERT(0);
delete[] buf;
And this does not have anything to do with GDI+ , this is only standard GDI functions.
The only thing you are using GDI+ for is loading images.
No offense though, just some constructive criticism!
EDIT:
I added weighting as well after the very important comment by Christian Graus....
-----------------------------
I am out of scope
|
|
|
|
|
Scope wrote: ( GetBValue( col ) + GetGValue( col ) + GetRValue( col ) ) / 3;
In fact, even this is wrong. A greyscale filter weights the three colors differently, in line with how the human eye percieves them. Not surprisingly, there are many accepted variations, but no-one writes an evenly weighted grey filter, it just doesn't work properly.
Christian Graus - Microsoft MVP - C++
Metal Musings - Rex and my new metal blog
|
|
|
|
|
Yeah I just took the gray-example because it had the least ammount of code to show how it should have been implemented. Proper weighting is another thing that probably should have been implemented as well. I think I saw some comment somewhere about proper grayscale weighting and it should be very easy to implement.
-----------------------------
I am out of scope
|
|
|
|
|
Thank you for your suggestion. I will change in my next version.
----------BAla--------------
|
|
|
|
|
What represent the number "41" in blurrin at linecode:
if ((nCount < ((m_nHeight-1)*m_nWidth*4l)) && (nCount > (m_nWidth*4)))
{
memcpy(&lVal, &pOriBuf[nCount-(m_nWidth*4l)], 4);
....
and so on...
???
Thanks!
|
|
|
|
|
Thank U.
COLORREF is 4bytes long. RGB -- 3bytes. Remain 1 bytes is empty(always 00).So i multiplied with 4.(l means type conversion for long)
----------BAla--------------
|
|
|
|
|
I thought that at first, too.
I think 4L works, too, just in case you want to avoid confusion when someone reads the code.
Just a suggestion.
A8
|
|
|
|
|
Which is the correct value for this thre variables???
|
|
|
|
|
I've resolved this problem...now I have an other question:
which represent the number "41" in blurrin at linecode:
if ((nCount < ((m_nHeight-1)*m_nWidth*4l)) && (nCount > (m_nWidth*4)))
{
memcpy(&lVal, &pOriBuf[nCount-(m_nWidth*4l)], 4);
....
and so on...
???
Thanks!
|
|
|
|
|
|
Thank U. Because bitmap using little endian model.
About endian: http://www.codeguru.com/cpp/cpp/algorithms/math/article.php/c10243/
----------BAla--------------
|
|
|
|
|
How to do with dithering or halftoning using GDI+ ?
|
|
|
|
|
Thank U. I have no idea abt dithering in GDI+ right now. If i know later, i will explain. Sorry......
We can do in mathematically. For your ref:
http://www.codeproject.com/cs/media/Image_Processing_Lab.asp
----------BAla--------------
|
|
|
|
|
Hi,
After change brightness or something, how to save changes using GDI+ ?
Thanks !
|
|
|
|
|
Thank U. I will upate later in my source code.
Add this 2 method.in CImageProcess class and pass arguments(m_hMemDC and file name)
/////////////////////////////////////////////////////////////////////////////////////////////////
// Method name : Save
// Arguments : HDC hMemDC, unsigned short *pszFileName
// Return type : void
// Precondition : gdiplus should be intialize
// Postcondition: None
/////////////////////////////////////////////////////////////////////////////////////////////////
void CImageProcess::Save(HDC hMemDC, unsigned short *pszFileName)
{
BITMAPINFO bi = {0};
// Bitmap header
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
bi.bmiHeader.biWidth = m_nWidth;
bi.bmiHeader.biHeight = m_nHeight;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 32;
bi.bmiHeader.biCompression = BI_RGB;
bi.bmiHeader.biSizeImage = m_nWidth * 4 * m_nHeight;
bi.bmiHeader.biClrUsed = 0;
bi.bmiHeader.biClrImportant = 0;
// Create tempravary file
FILE* fp = fopen("C:\\Temp.bmp", "wb");
if (fp==0)
{
return;
}
char *tmpBuf = (char *) malloc(m_nWidth * 4 * m_nHeight);
int bRes = GetDIBits(hMemDC, m_hBitmap, 0, m_nHeight, tmpBuf, &bi,
DIB_RGB_COLORS);
BITMAPFILEHEADER bfh = {0};
// Bitmap Header format
bfh.bfType=('M'<< 8) + 'B';
bfh.bfOffBits=sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bfh.bfSize= bi.bmiHeader.biSizeImage + bfh.bfOffBits;
fwrite(&bfh,sizeof(bfh), 1, fp);
fwrite(&bi.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp);
fwrite(tmpBuf, bi.bmiHeader.biSizeImage, 1, fp);
fclose(fp);
unsigned short int wszFileName[MAX_PATH] = {0};
mbstowcs(wszFileName, "Temp.bmp", -1);
Image img(wszFileName);
CLSID clsid;
// JPG
if (wcsstr(pszFileName, L".jpg") || wcsstr(pszFileName, L".jpeg") ||
wcsstr(pszFileName, L".JPG") || wcsstr(pszFileName, L".JPEG"))
{
GetEncoderClsid(L"image/jpeg", &clsid);
}
// PNG
else if (wcsstr(pszFileName, L".png") || wcsstr(pszFileName, L".PNG"))
{
GetEncoderClsid(L"image/png", &clsid);
}
// GIF
else if (wcsstr(pszFileName, L".gif") || wcsstr(pszFileName, L".GIF"))
{
GetEncoderClsid(L"image/gif", &clsid);
}
// BMP
else if (wcsstr(pszFileName, L".bmp") || wcsstr(pszFileName, L".BMP"))
{
GetEncoderClsid(L"image/bmp", &clsid);
}
// TIFF
else if (wcsstr(pszFileName, L".tif") || wcsstr(pszFileName, L".TIF"))
{
GetEncoderClsid(L"image/tiff", &clsid);
}
img.Save(pszFileName, &clsid, NULL);
// Delete tempravary file
DeleteFile(_T("C:\\Temp.bmp"));
}
// Get the class id for particular format
int CImageProcess::GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array in bytes
ImageCodecInfo* pImageCodecInfo = NULL;
GetImageEncodersSize(&num, &size);
if(size == 0)
return -1; // Failure
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
return -1; // Failure
GetImageEncoders(num, size, pImageCodecInfo);
for(UINT j = 0; j < num; ++j)
{
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // Success
}
}
free(pImageCodecInfo);
return -1; // Failure
}
----------BAla--------------
|
|
|
|
|
Hi bala
This is a good sample application .
I tryed to implement Save image function . But i do not work .
It created a modified image in "C:/temp.bmp" afert that it delete it .
But changes r not reflected in original image .
Need u r inputs
Thanks in advance .
Kiran Chikhale
|
|
|
|
|