user-0 提问: 用c语言读写bmp图像，请问为什么读出来的图像的高和宽不对？这个代码哪里出现了问题？麻烦大神们帮我解答一下！谢谢

回复:
user: user-0
content: 引用 10 楼 赵4老师的回复:再供参考：#include <math.h> #include <string.h> #include <stdio.h> #include <windows.h> #include <gdiplus.h> #pragma comment(lib, "gdiplus.lib") using namespace Gdiplus; wchar_t formats[5][11]={     L"image/bmp",     L"image/jpeg",     L"image/gif",     L"image/tiff",     L"image/png", }; wchar_t exts[5][5]={     L".bmp",     L".jpg",     L".gif",     L".tif",     L".png", }; int 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 } int wmain(int argc,wchar_t *argv[]) {     int r=1;     if (argc<4) {     USAGE:         wprintf(L"%s srcimg.{bmp|jpg|gif|tif|png|wmf|emf|ico}  desimg.{bmp|jpg|gif|tif|png}  angle\n",argv[0]);         return r;     }     int i;     for (i=0;i<5;i++) {         if (0==_wcsicmp(argv[1]+wcslen(argv[1])-4,exts[i])) break;     }     if (i>=5) goto USAGE;     for (i=0;i<5;i++) {         if (0==_wcsicmp(argv[2]+wcslen(argv[2])-4,exts[i])) break;     }     if (i>=5) goto USAGE;     GdiplusStartupInput gdiplusstartupinput;     ULONG_PTR gdiplustoken;     GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);     {         Image img(argv[1]);         if (Ok==img.GetLastStatus()) {             UINT height = img.GetHeight();             UINT width  = img.GetWidth();             REAL angle;             if (1==swscanf_s(argv[3],L"%f",&angle)) {                 REAL size;                 size=(REAL)sqrt(1.0*width*width+1.0*height*height);                 Matrix mat;                 mat.Translate(size / -2.0f, size / -2.0f);                 mat.Rotate(-angle, MatrixOrderAppend);                 mat.Translate(size / 2.0f, size / 2.0f, MatrixOrderAppend);                 PointF pfTL((size-width)/2.0f      ,(size-height)/2.0f       );                 PointF pfTR((size-width)/2.0f+width,(size-height)/2.0f       );                 PointF pfBL((size-width)/2.0f      ,(size-height)/2.0f+height);                 PointF pfBR((size-width)/2.0f+width,(size-height)/2.0f+height);                 Graphics tgp(&img);                 Bitmap bmp((UINT)size,(UINT)size,&tgp);//Let bmp Resolution equal to img Resolution                 Graphics gp(&bmp);                 gp.SetTransform(&mat);                 gp.DrawImage(&img,pfTL);                 REAL xmin,ymin,xmax,ymax,x,y,rw,rh;                 mat.TransformPoints(&pfTL);                 xmin=xmax=pfTL.X;                 ymin=ymax=pfTL.Y;                 mat.TransformPoints(&pfTR);                 if (xmin>pfTR.X) xmin=pfTR.X;                 if (xmax<pfTR.X) xmax=pfTR.X;                 if (ymin>pfTR.Y) ymin=pfTR.Y;                 if (ymax<pfTR.Y) ymax=pfTR.Y;                 mat.TransformPoints(&pfBL);                 if (xmin>pfBL.X) xmin=pfBL.X;                 if (xmax<pfBL.X) xmax=pfBL.X;                 if (ymin>pfBL.Y) ymin=pfBL.Y;                 if (ymax<pfBL.Y) ymax=pfBL.Y;                 mat.TransformPoints(&pfBR);                 if (xmin>pfBR.X) xmin=pfBR.X;                 if (xmax<pfBR.X) xmax=pfBR.X;                 if (ymin>pfBR.Y) ymin=pfBR.Y;                 if (ymax<pfBR.Y) ymax=pfBR.Y;                 x=xmin;                 y=ymin;                 rw=xmax-x;                 rh=ymax-y;                 Bitmap* clone;                 clone = bmp.Clone(x,y,rw,rh,PixelFormat24bppRGB);//bmp.GetPixelFormat()                 CLSID encoderClsid;                 if (0<=GetEncoderClsid(formats[i],&encoderClsid)) {                     if (Ok==clone->Save(argv[2],&encoderClsid)) {                         wprintf(L"OK to %s  %s  %s  %s\n",argv[0],argv[1],argv[2],argv[3]);                         r=0;                     } else {                         wprintf(L"Error to save %s\n",argv[2]);                         r=4;                     }                 } else {                     wprintf(L"Error to GetEncoderClsid(%s,...)\n",formats[i]);                     r=3;                 }                 delete clone;             } else {                 wprintf(L"Error to get angle %s\n",argv[3]);                 r=2;             }         } else {             wprintf(L"Error to load %s\n",argv[1]);             r=5;         }     }     GdiplusShutdown(gdiplustoken);     return r; }  谢谢赵老师啦

user: user-1
content: 再供参考：#include <math.h> #include <string.h> #include <stdio.h> #include <windows.h> #include <gdiplus.h> #pragma comment(lib, "gdiplus.lib") using namespace Gdiplus; wchar_t formats[5][11]={     L"image/bmp",     L"image/jpeg",     L"image/gif",     L"image/tiff",     L"image/png", }; wchar_t exts[5][5]={     L".bmp",     L".jpg",     L".gif",     L".tif",     L".png", }; int 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 } int wmain(int argc,wchar_t *argv[]) {     int r=1;     if (argc<4) {     USAGE:         wprintf(L"%s srcimg.{bmp|jpg|gif|tif|png|wmf|emf|ico}  desimg.{bmp|jpg|gif|tif|png}  angle\n",argv[0]);         return r;     }     int i;     for (i=0;i<5;i++) {         if (0==_wcsicmp(argv[1]+wcslen(argv[1])-4,exts[i])) break;     }     if (i>=5) goto USAGE;     for (i=0;i<5;i++) {         if (0==_wcsicmp(argv[2]+wcslen(argv[2])-4,exts[i])) break;     }     if (i>=5) goto USAGE;     GdiplusStartupInput gdiplusstartupinput;     ULONG_PTR gdiplustoken;     GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);     {         Image img(argv[1]);         if (Ok==img.GetLastStatus()) {             UINT height = img.GetHeight();             UINT width  = img.GetWidth();             REAL angle;             if (1==swscanf_s(argv[3],L"%f",&angle)) {                 REAL size;                 size=(REAL)sqrt(1.0*width*width+1.0*height*height);                 Matrix mat;                 mat.Translate(size / -2.0f, size / -2.0f);                 mat.Rotate(-angle, MatrixOrderAppend);                 mat.Translate(size / 2.0f, size / 2.0f, MatrixOrderAppend);                 PointF pfTL((size-width)/2.0f      ,(size-height)/2.0f       );                 PointF pfTR((size-width)/2.0f+width,(size-height)/2.0f       );                 PointF pfBL((size-width)/2.0f      ,(size-height)/2.0f+height);                 PointF pfBR((size-width)/2.0f+width,(size-height)/2.0f+height);                 Graphics tgp(&img);                 Bitmap bmp((UINT)size,(UINT)size,&tgp);//Let bmp Resolution equal to img Resolution                 Graphics gp(&bmp);                 gp.SetTransform(&mat);                 gp.DrawImage(&img,pfTL);                 REAL xmin,ymin,xmax,ymax,x,y,rw,rh;                 mat.TransformPoints(&pfTL);                 xmin=xmax=pfTL.X;                 ymin=ymax=pfTL.Y;                 mat.TransformPoints(&pfTR);                 if (xmin>pfTR.X) xmin=pfTR.X;                 if (xmax<pfTR.X) xmax=pfTR.X;                 if (ymin>pfTR.Y) ymin=pfTR.Y;                 if (ymax<pfTR.Y) ymax=pfTR.Y;                 mat.TransformPoints(&pfBL);                 if (xmin>pfBL.X) xmin=pfBL.X;                 if (xmax<pfBL.X) xmax=pfBL.X;                 if (ymin>pfBL.Y) ymin=pfBL.Y;                 if (ymax<pfBL.Y) ymax=pfBL.Y;                 mat.TransformPoints(&pfBR);                 if (xmin>pfBR.X) xmin=pfBR.X;                 if (xmax<pfBR.X) xmax=pfBR.X;                 if (ymin>pfBR.Y) ymin=pfBR.Y;                 if (ymax<pfBR.Y) ymax=pfBR.Y;                 x=xmin;                 y=ymin;                 rw=xmax-x;                 rh=ymax-y;                 Bitmap* clone;                 clone = bmp.Clone(x,y,rw,rh,PixelFormat24bppRGB);//bmp.GetPixelFormat()                 CLSID encoderClsid;                 if (0<=GetEncoderClsid(formats[i],&encoderClsid)) {                     if (Ok==clone->Save(argv[2],&encoderClsid)) {                         wprintf(L"OK to %s  %s  %s  %s\n",argv[0],argv[1],argv[2],argv[3]);                         r=0;                     } else {                         wprintf(L"Error to save %s\n",argv[2]);                         r=4;                     }                 } else {                     wprintf(L"Error to GetEncoderClsid(%s,...)\n",formats[i]);                     r=3;                 }                 delete clone;             } else {                 wprintf(L"Error to get angle %s\n",argv[3]);                 r=2;             }         } else {             wprintf(L"Error to load %s\n",argv[1]);             r=5;         }     }     GdiplusShutdown(gdiplustoken);     return r; }

user: user-1
content: 使用GDI+读图片文件1.jpg并将每个像素的x，y和r，g，b值保存到color.txt中。

user: user-0
content: 引用 3 楼 user-3的回复:你的图片没问题吧？我这里测试是对的 我再找张图片试试

user: user-0
content: 引用 4 楼 ooolinux的回复:[quote=引用 2 楼 qq_34526102 的回复:] [quote=引用 1 楼 ooolinux的回复:]有很多库/函数可以读取图像文件，如果为了应用不需要自己钻研文件格式吧，软件代码是需要复用的。 因为后面要用插值法对图像进行修复，去噪和缩放， 上面那个代码是课本上的， 先读取文件，还要获取像素之类的。但是我的输出并不正确。【确[/quote]  库/函数都是可以获取每个像素的，可以修改每个像素，最后存入文件。 BMP还好点，如果是JPG文件，自己写代码估计够呛。[/quote] 好哒，我去试一下，谢谢

user: user-2
content: 引用 2 楼 qq_34526102 的回复:[quote=引用 1 楼 ooolinux的回复:]有很多库/函数可以读取图像文件，如果为了应用不需要自己钻研文件格式吧，软件代码是需要复用的。 因为后面要用插值法对图像进行修复，去噪和缩放， 上面那个代码是课本上的， 先读取文件，还要获取像素之类的。但是我的输出并不正确。【确[/quote]  库/函数都是可以获取每个像素的，可以修改每个像素，最后存入文件。 BMP还好点，如果是JPG文件，自己写代码估计够呛。

user: user-0
content: 引用 7 楼 赵4老师的回复:仅供参考：#include <iostream> #include <fstream> #include <string> #include <windows.h> #include <gdiplus.h> #pragma comment(lib, "gdiplus.lib")  using namespace std; using namespace Gdiplus;  int main() {     GdiplusStartupInput gdiplusstartupinput;     ULONG_PTR gdiplustoken;     GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);      wstring infilename(L"1.jpg");     string outfilename("color.txt");      Bitmap* bmp = new Bitmap(infilename.c_str());     UINT height = bmp->GetHeight();     UINT width  = bmp->GetWidth();     cout << "width " << width << ", height " << height << endl;      Color color;     ofstream fout(outfilename.c_str());      for (UINT y = 0; y < height; y++)     for (UINT x = 0; x < width ; x++) {             bmp->GetPixel(x, y, &color);             fout << x << "," << y << ";"                  << (int)color.GetRed()   << ","                  << (int)color.GetGreen() << ","                  << (int)color.GetBlue()  << endl;     }      fout.close();      delete bmp;     GdiplusShutdown(gdiplustoken);     return 0; }  菜鸟一只，看不太懂啊啊！不过还是谢谢您啦

user: user-3
content: 你的图片没问题吧？我这里测试是对的

user: user-0
content: 引用 1 楼 ooolinux的回复:有很多库/函数可以读取图像文件，如果为了应用不需要自己钻研文件格式吧，软件代码是需要复用的。 因为后面要用插值法对图像进行修复，去噪和缩放， 上面那个代码是课本上的， 先读取文件，还要获取像素之类的。但是我的输出并不正确。【确

user: user-1
content: 仅供参考：#include <iostream> #include <fstream> #include <string> #include <windows.h> #include <gdiplus.h> #pragma comment(lib, "gdiplus.lib")  using namespace std; using namespace Gdiplus;  int main() {     GdiplusStartupInput gdiplusstartupinput;     ULONG_PTR gdiplustoken;     GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);      wstring infilename(L"1.jpg");     string outfilename("color.txt");      Bitmap* bmp = new Bitmap(infilename.c_str());     UINT height = bmp->GetHeight();     UINT width  = bmp->GetWidth();     cout << "width " << width << ", height " << height << endl;      Color color;     ofstream fout(outfilename.c_str());      for (UINT y = 0; y < height; y++)     for (UINT x = 0; x < width ; x++) {             bmp->GetPixel(x, y, &color);             fout << x << "," << y << ";"                  << (int)color.GetRed()   << ","                  << (int)color.GetGreen() << ","                  << (int)color.GetBlue()  << endl;     }      fout.close();      delete bmp;     GdiplusShutdown(gdiplustoken);     return 0; }

user: user-2
content: 有很多库/函数可以读取图像文件，如果为了应用不需要自己钻研文件格式吧，软件代码是需要复用的。