0

そのため、フォルダーからランダムな画像を取得し、それらからコラージュを作成し、それを Windows の壁紙に設定するプログラムがあります。これはうまくいくようです。そこで、スリープ タイマーを入れて、30 分おきに実行しなくても自動的に更新されるようにしようと考えました。私はそれを行い、うまく機能しましたが、ループを開始する前に気付かなかったメモリリークの問題に遭遇しました。GDI+ オブジェクトを破棄しようとしていますが、破棄は GDIplus::Image のメンバーではないというエラーが表示され続けます。

画像を Image オブジェクトにロードし、サイズを変更して画像の配列に入れています。次に、最初の画像を破棄したいと思います。配列内の画像の操作が終了したら、配列を破棄したいと思います。

これは、VS2005 の古いコピーで行われています。

#include <windows.h>
#include <objidl.h>
#include <gdiplus.h>
#include <string>
#include <iostream>
#include <vector>
#include <dirent.h>
#include <time.h>
#include <fstream>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include "cwp05rnd.h"

using namespace Gdiplus;
using namespace std;
#pragma comment (lib,"Gdiplus.lib")
#pragma comment (lib, "user32.lib")

int main()
{
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR           gdiplusToken;
HDC                 hdc;
Graphics            graphics(hdc);

GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
CLSID jpegClsid;
GetEncoderClsid(L"image/jpeg", &jpegClsid);

SetCurrentDirectoryA("E:\\Photos");
ofstream outfile;
outfile.open ("outimgs.txt");
ofstream outfile2;
outfile2.open("imgpos.txt");

srand(time(NULL));
init_genrand(time(NULL));

vector<string>  dirlist;
DIR             *d;
struct          dirent *dir;

int i=0;
d=opendir(".");
if (d)
{
    while ((dir=readdir(d)) != NULL)
    {
        i++;
        dirlist.push_back(dir->d_name);
    }
    closedir(d);
}
Image   wp(L"E:\\Dropbox\\Photos\\wallpaper.jpg");
Graphics* wpimage = Graphics::FromImage(&wp);
int r;
int rvsize=100;
int rv[100]={0};
string img;
std::wstring wimg;
const wchar_t* rimg;
double cwidth;
double cheight;
double ratio;
int nheight;
int counter=0;
    int full = 0;
    int tries = 0;
    int hfull = 0;
    int imgnum =0;
    int last=0;
    Image* newpic[10];

    while ( tries <10)
    {
        redo:
        tries++;
        int newrv=0;
        while (newrv ==0)
        {

            r=genrand_int32()%i;
            for (int k=0; k < rvsize; k++)
            {

                if (rv[k] > 0 && rv[k]==r )
                {
                    break;
                }
                if (rv[k]==0 && r < i)
                {
                    newrv =1;
                    rv[k]=r;
                    last=k;
                    break;
                }
                if (rv[k] ==0)
                {
                    break;
                }
            }

        }
        img = dirlist[r];
        if (img[0]=='.')
        {
            newrv=0;
            goto redo;
        }
        wimg = std::wstring(img.begin(),img.end());

        rimg = wimg.c_str();

        Image pic(rimg);

        cwidth = pic.GetWidth();
        cheight = pic.GetHeight();
        if (cheight ==0)
        {
            outfile2 << "error" << img << endl;
            rv[last]=0;
            system("pause");
            goto redo;
        }
        ratio = cwidth/cheight;
        nheight = nwidth/ratio;
        pic.RotateFlip(Rotate180FlipNone);
        pic.RotateFlip(Rotate180FlipNone);
        newpic[imgnum] = pic.GetThumbnailImage(nwidth,nheight,NULL,NULL);
                    delete pic[0];
                    imgnum = imgnum + 1;
        }

次に、さまざまなランダム値に従って、newpic の画像にフリップと回転の長いセクションがあります。

wpimage->DrawImage(newpic[k],(j*nwidth),(((k+1)*whitespace)+htot),nwidth,nh[k]);
wp.Save(L"C:\\Temp\\wallpaper\\nwallpaper.jpg", &jpegClsid, NULL);
delete newpic;
setWall();
delete wpimage;
delete wp;
return 0;
}

Image オブジェクトを削除しようとすると、ポインターではないオブジェクトを削除できないか、GDIplus::Image から void* に変換できないというエラーが表示されます。

アドバイスをいただければ幸いです。

4

1 に答える 1

0

私はあなたが持っていることに気付きましたがImage pic(rimg); 、あなたがやっているdelete pic[0]; picのはポインターではありません..動的に割り当てられたものでもありません...また、配列でもありません(または、そうかもしれません..しかし、直感的にはないと思います..)

* 追加 * そうそう、すでにこれを解決している場合は、質問を閉じるか、少なくとも言及することをお勧めします...

于 2014-03-04T23:37:05.830 に答える