0

ウェブサイトの画像ハンドラーを作成しようとしていますが、基本的なサイズ変更、回転、トリミングが機能し、ウェブサイトで正常に表示されますが、ファイルを保存してハンドラーにキャッシュを追加しようとしました/chached/filename.pngが、何らかの理由でキャッシュを追加しました、画像ハンドラーが間違った画像を返しています。たとえば、サイズ変更されたプロジェクト画像が表形式で表示されるプロジェクトリストページがありますが、最初の4つのプロジェクトは同じ画像で表示され、次の4つのプロジェクトは異なる画像ですべて同じであるなどと表示されます。

せいresponse.outputstreamなのかと思いますが、次の画像が呼び出される前に最初の画像を完成させるのに十分な時間がないようですので、よくわかりません。

念のため、完全なコードはここで入手できます:http: //pastebin.com/BNyDfqPy

私のプロセスリクエスト方法は次のとおりです。

public void ProcessRequest(HttpContext context)
{
    // Settings and locations
    appPath = HttpContext.Current.Request.PhysicalApplicationPath;
    location = context.Request.QueryString["image"];
    cacheLocation = Path.GetDirectoryName(appPath + location) + "/Cached/";

    // Input/Output
    Bitmap bitOutput;
    Bitmap bitInput = GetImage(context);

    if (cacheAvailable)
    {
        bitOutput = bitInput;
    }
    else
    {
        try
        {
            Boolean crop = false;

            if (context.Request["type"] == "crop")
            {
                crop = true;
            }

            bitInput = RotateFlipImage(context, bitInput);

            if (hasSetSize)
            {
                Int32 x = String.IsNullOrEmpty(context.Request["x"]) ? 0 : Int32.Parse(context.Request["x"]);
                Int32 y = String.IsNullOrEmpty(context.Request["y"]) ? 0 : Int32.Parse(context.Request["y"]);

                bitOutput = ResizeImage(bitInput, _width, _height, crop, x, y);

                bitOutput.Save(cacheLocation + cacheKey + ".png", System.Drawing.Imaging.ImageFormat.Png);
            }
            else
            {
                throw new Exception();
            }
        }
        catch (Exception)
        {
            bitOutput = bitInput;
        }
    }


    context.Response.Clear();
    context.Response.Cache.SetNoStore();
    context.Response.ContentType = "image/png";

    using (MemoryStream ms = new MemoryStream())
    {
        bitOutput.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        ms.WriteTo(context.Response.OutputStream);
    }
    //bitOutput.Save(context.Response.OutputStream, System.Drawing.Imaging.ImageFormat.Png);

    bitOutput.Dispose();
    bitInput.Dispose();
    context.Response.Flush();

    return;        
}

そして、私はこれを使用して画像を取得します:

public Bitmap GetImage(HttpContext context)
{
    // Get location
    Bitmap bitOutput = null;

    try
    {
        if (!String.IsNullOrEmpty(location))
        {
            Image image = Image.FromFile(appPath + location);
            bitOutput = new Bitmap(image);
            hasSetSize = SetHeightWidth(context, bitOutput);

            if (!System.IO.Directory.Exists(cacheLocation))
            {
                System.IO.Directory.CreateDirectory(cacheLocation);
            }

            // Generate cache key
            cacheKey = "imagehandler_" + _width + "x" + _height + "_" + context.Request["RotateFlip"] + context.Request["type"];

            if (File.Exists(cacheLocation + cacheKey + ".png"))
            {
                image = Image.FromFile(cacheLocation + cacheKey + ".png");
                bitOutput = new Bitmap(image);
                cacheAvailable = true;
            }
        }
        else
        {
            throw new Exception("Can't load original or save to cache, check directory permissions!");
        }
    }
    catch (Exception)
    {
        Image image = Image.FromFile(appPath + noImageUrl);
        bitOutput = new Bitmap(image);
    }

    return bitOutput;
}

私もisReusable次のように設定しました:

public bool IsReusable
{
    get
    {
        return false;
    }
}

出力は次の画像のようになります。プロジェクトごとに異なる画像セットがありますが、前/次の画像と同じ画像、独自の画像(私が欲しいもの)、またはプレースホルダー画像のいずれかが表示されます。

異なる画像を持つことになっているプロジェクトのリスト

4

2 に答える 2

2

私が見るように、あなたはおそらく静的変数を使用していてcacheAvailable、その後はtrueに設定されていても、次の呼び出しでfalseに戻らないでしょう。

したがってcacheAvailable、すべてのリクエストのデフォルトとしてfalseを設定する場合は確認してください。

于 2012-12-22T13:29:54.787 に答える
0

まず、ハンドラーが同じインスタンスを何度も使用できるようにする必要がない限り、IsReusablefalseを返します。

それをしたくない場合は、cacheAvailableクラスレベル変数を削除し、次のように変更します。

// Input/Output
Bitmap bitOutput;
Bitmap bitInput = GetImage(context);

これに:

// Input/Output
Bitmap bitOutput;
bool cacheAvailable;
Bitmap bitInput = GetImage(context, out cacheAvailable);

そして、GetImageこのように変更します

public Bitmap GetImage(HttpContext context, out bool cacheAvailable)
{
    // Get location
    Bitmap bitOutput = null;
    cacheAvailable = false;

    try
    {
        if (!String.IsNullOrEmpty(location))
        {
            Image image = Image.FromFile(appPath + location);
            bitOutput = new Bitmap(image);
            hasSetSize = SetHeightWidth(context, bitOutput);

            if (!System.IO.Directory.Exists(cacheLocation))
            {
                System.IO.Directory.CreateDirectory(cacheLocation);
            }

            // Generate cache key
            cacheKey = "imagehandler_" + _width + "x" + _height + "_" + context.Request["RotateFlip"] + context.Request["type"];

            if (File.Exists(cacheLocation + cacheKey + ".png"))
            {
                image = Image.FromFile(cacheLocation + cacheKey + ".png");
                bitOutput = new Bitmap(image);
                cacheAvailable = true;
            }
        }
        else
        {
            throw new Exception("Can't load original or save to cache, check directory permissions!");
        }
    }
    catch (Exception)
    {
        Image image = Image.FromFile(appPath + noImageUrl);
        bitOutput = new Bitmap(image);
    }

    return bitOutput;
}
于 2012-12-22T13:38:14.210 に答える