在c ++,PNG,JPEG上打开图像文件

时间:2016-05-20 00:25:45

标签: c++

我试图打开bg.png文件,但没有用。没有错误,但没有出现任何错误。帮助我!

int main()
    {
        initwindow(600,600,"GAME");
        ifstream image("bg.png");
        getimage(50, 50 , 450 , 450 , image);
        putimage(50,50,image,COPY_PUT);
        system("pause");
    }

3 个答案:

答案 0 :(得分:1)

此:

ifstream image("bg.png");

...以文本模式打开文件,其中,在Windows和旧Mac上,表示行尾和文本结尾的某些字节序列在输入和输出上更改。

你不想要那个。

Specify binary mode

也就是说,你在C ++中最接近“标准”图像处理的是Boost Image library

答案 1 :(得分:0)

来自 Borland graphics.h是古老的 BGI 库我找到了这个文档:

因此,这只是将图像从屏幕复制到一些内存缓冲区(以允许反向缓冲技术)。您使用ifstream来调用它是错误的。您正在使用内存缓冲区或其指针指向的区域覆盖指针(取决于getimage行为)。如果您确实想要使用 BGI ,请将图像解码为内存并使用putimage进行查看。但我担心它不是用RAW编码的,更安全的是用像素访问直接绘制图像。

当我写到你的另一个问题时你需要使用一些lib或编码解码你自己的图像。 iostream不是一个好方法。

对于 MS-DOS ,使用操作系统 api(int 21h如果您没有正确覆盖它的功能)...对于 Windows Borland 环境使用FileOpen FileRead FileClose。对于非Borland环境,请使用来自目标操作系统的WinAPI或相关 API (如果不是Windows)。要解码图像,首先需要选择文件格式进行解码我建议先从 PCX,BMP (限制为单像素格式)或 TGA 开始。像 JPG,PNG,GIF 这样的文件格式对于新手编码器而言实在太过分了。例如,我的 GIF 解码器/编码器在C ++中约为36 KByte源代码+另一个15 KBytes用于文件 CACHE 缓冲和多线程RT 编码调度程序。与 PCX 相比,加载/解码的代码大约为1.5KByte

这是我在 Borland / Embarcadero VCL C ++ Windows 中将纹理加载到我的GL引擎中的一个小例子:

int picture_load(Graphics::TBitmap *bmp,AnsiString name,int *_alpha)
    {
    if (bmp==NULL)        { _errorlog+="picture_load bmp is NULL\n"; return 0; }
    if (!FileExists(name)){ _errorlog+="picture_load file \""+name+"\" dont exist\n"; return 0; }
    bmp->HandleType=bmDIB;
    bmp->PixelFormat=pf32bit;
    AnsiString ext=ExtractFileExt(name).LowerCase();
    for(;;)
        {
        if (ext==".bmp")
            {
            bmp->LoadFromFile(name);
            break;
            }
        if (ext==".jpg")
            {
            TJPEGImage *jpg=new TJPEGImage;
            #ifdef _mmap_h
            if (jpg) mmap_new('GL',jpg,sizeof(TJPEGImage));
            #endif
            if (jpg==NULL) { _errorlog+="picture_load not enough memory\n"; return 0; }
            jpg->LoadFromFile(name);
            bmp->Assign(jpg);
            #ifdef _mmap_h
            mmap_del('GL',jpg);
            #endif
            delete jpg;
            break;
            }
        if (ext==".png")
            {
            TPNGObject *png=new TPNGObject;
            #ifdef _mmap_h
            if (png) mmap_new('GL',png,sizeof(TJPEGImage));
            #endif
            if (png==NULL) { _errorlog+="picture_load not enough memory\n"; return 0; }
            png->LoadFromFile(name);
            bmp->Assign(png);
            #ifdef _mmap_h
            mmap_del('GL',png);
            #endif
            delete png;
            break;
            }
        if ((ext==".sgi")||(ext==".rgb"))
            {
            sgi sss;
            sss.load(name);
            bmp->Width=sss.rgba->Width;
            bmp->Height=sss.rgba->Height;
            bmp->Canvas->Draw(0,0,sss.rgba);
            break;
            }
        if (ext==".pcx")
            {
            unsigned int *p,c;
            int     x,y,adr;
            int hnd,siz,l,xs,ys;
            unsigned int pal[256],r,g,b;
            Byte *dat;
            for(;;)
                {
                hnd=FileOpen(name,fmOpenRead);
                if (hnd<0) { _errorlog+="picture_load file \""+name+"\" dont exist\n"; return 0; }
                siz=FileSeek(hnd,0,2);
                FileSeek(hnd,0,0);
                dat=new Byte[siz];
                #ifdef _mmap_h
                if (dat) mmap_new('GL',dat,siz*sizeof(BYTE));
                #endif
                if (dat==NULL) { FileClose(hnd); _errorlog+="picture_load not enough memory\n"; return 0; }
                FileRead(hnd,dat,siz);
                FileClose(hnd);
                adr=siz-3*256;
                for (l=0;l<256;l++)
                    {
                    r=dat[adr]; adr++; r&=255;
                    g=dat[adr]; adr++; g&=255;
                    b=dat[adr]; adr++; b&=255;
                    c=(r<<16)|(g<<8)|(b);
                    c&=0x00FFFFFF;
                    pal[l]=c;
                    }
                xs=int(dat[ 8])-int(dat[4])+((int(dat[ 9])-int(dat[5]))<<8)+1;
                ys=int(dat[10])-int(dat[6])+((int(dat[11])-int(dat[7]))<<8)+1;

                bmp->HandleType=bmDIB;
                bmp->PixelFormat=pf32bit;
                bmp->Width=xs;
                bmp->Height=ys;
                xs=bmp->Width;
                ys=bmp->Height;

                adr=128;
                for (y=0;y<ys;y++)
                    {
                    p=(unsigned int*)bmp->ScanLine[y];
                    for (x=0;x<xs;)
                        {
                        c=dat[adr];
                        if (c<192) l=1;
                        else{
                            l=c&63;
                            adr++;
                            c=dat[adr];
                            }
                        adr++;
                        for (;l>0;l--)
                            {
                            if (x>=xs) break;
                            p[x]=pal[c];
                            x++;
                            }
                        }
                    }
                #ifdef _mmap_h
                mmap_del('GL',dat);
                #endif
                delete[] dat;
                break;
                }
            break;
            }
        if (ext==".dds")
            {
            DDS::load(bmp,name);
            _errorlog+=DDS::_errorlog;
            DDS::_errorlog="";
            break;
            }
        _errorlog+="picture_load unsuported file extension \""+ext+"\"\n";
        return 0;
        }
    bmp->HandleType=bmDIB;
    if (_alpha) _alpha[0]=(bmp->PixelFormat==pf32bit);
    bmp->PixelFormat=pf32bit;
    return 1;
    }

由于您的代码看起来像是在 MS-DOS ,这将无效。但是你可以提取不使用任何lib的 PCX 部分。只需移植代码(用你可以使用的功能替换AnsiString和文件访问权限)

Graphics::TBitmap VCL / GDI 位图以了解其用途,请参阅:

因此,您可以将此移植到 BGI 。此外,您可以忽略与此相关的内存泄漏跟踪/调试中剩余的所有#ifdef _mmap_h内容:

看看PCX file-format specification

答案 2 :(得分:-1)

您确定bg.png位于运行程序的同一文件夹中吗?如果答案是肯定的,你试过吗?

int main()
    {
        int wHANDLE=initwindow(600,600,"GAME");
        setcurrentwindow(wHANDLE);
        ifstream image("bg.png");
        getimage(50, 50 , 450 , 450 , image);
        putimage(50,50,image,COPY_PUT);
        system("pause");
    }