尝试将生成的热图保存在Azure存储中

| 我有一个Heatmap,目前可以在将其移植到Azure存储的独立服务器上使用。如何将butmap文件保存在Azure存储中。最初,我在web.config文件中有一个条目,将图像缓存指向花药驱动器(IE)上的直接路径,现在所有内容都将位于“存储帐户”中的〜/ map_cache文件夹中。如何修改此参数以在Azure中本地存储。
protected void Page_Load(object sender, EventArgs e)
{
    xxxxxxxdb = new xxxxxxx(ConfigurationManager.AppSettings[\"xxxxxxx\"]);

    string imageCachePath = Server.MapPath(\"/map_cache/HotSpots\");
    int fileExpirationTime = int.Parse(ConfigurationManager.AppSettings[\"HotspotImageExpirationTime\"]);
    Bitmap bitmap;

    string requestParam = Page.Request.Params[\"id\"];
    string bitmapFileName = Path.Combine(imageCachePath, requestParam + \".png\");
    if (File.Exists(bitmapFileName) && File.GetCreationTime(bitmapFileName) > DateTime.Now.AddHours(-fileExpirationTime))
    {
        bitmap = (Bitmap)Image.FromFile(bitmapFileName);
    }
    else
    {
        int zoomLevel = requestParam.Length;

        double tileX = 0;
        double tileY = 0;
        for (int index = 0; index < zoomLevel; index++)
        {
            int digit = int.Parse(requestParam[index].ToString());
            tileY += ((digit & 2) / 2) * Math.Pow(2, (zoomLevel - index - 1));
            tileX += (digit & 1) * Math.Pow(2, (zoomLevel - index - 1));
        }
        double pixelXMin = tileX * 256;
        double pixelYMin = tileY * 256;
        double pixelXMax = (tileX + 1) * 256 - 1;
        double pixelYMax = (tileY + 1) * 256 - 1;

        double longMin = ((pixelXMin * 360) / (256 * Math.Pow(2, zoomLevel))) - 180;
        double longMax = ((pixelXMax * 360) / (256 * Math.Pow(2, zoomLevel))) - 180;
        double latMin = Math.Asin((Math.Exp((0.5 - pixelYMin / 256 / Math.Pow(2, zoomLevel)) * 4 * Math.PI) - 1) /
                                  (Math.Exp((0.5 - pixelYMin / 256 / Math.Pow(2, zoomLevel)) * 4 * Math.PI) + 1)) * 180 /
                        Math.PI;
        double latMax = Math.Asin((Math.Exp((0.5 - pixelYMax / 256 / Math.Pow(2, zoomLevel)) * 4 * Math.PI) - 1) /
                                  (Math.Exp((0.5 - pixelYMax / 256 / Math.Pow(2, zoomLevel)) * 4 * Math.PI) + 1)) * 180 /
                        Math.PI;

        double pixelResolution = (Math.Cos(latMax * Math.PI / 180) * 2 * Math.PI * 6378137) / (256 * Math.Pow(2, zoomLevel));
        double pixelArea = Math.Pow(pixelResolution, 2);

        double maxHotspotDensity = Math.Max(120.0 / zoomLevel, 3.0) / pixelArea;

        bitmap = GenerateBlankBitmap();

        var accidents = from hs in db.cs_PT_VEGeoDatas
                        where hs.Latitude <= latMin && hs.Latitude >= latMax
                              && hs.Longitude >= longMin && hs.Longitude <= longMax
                        select new { hs.Latitude, hs.Longitude };

        Dictionary<Point, HotSpot> hotSpots = new Dictionary<Point, HotSpot>();
        foreach (var accident in accidents)
        {
            int pixelX, pixelY;
            LatLongToPixelXY(accident.Latitude, accident.Longitude, zoomLevel, out pixelX, out pixelY);
            pixelX %= 256;
            pixelY %= 256;
            for (int ix = -doublePixelSize; ix <= doublePixelSize; ix++)
            {
                for (int iy = -doublePixelSize; iy <= doublePixelSize; iy++)
                {
                    Point point;
                    bool borderPoint = false;
                    if (zoomLevel < doublePixelZoomLevel)
                    {
                        point = new Point(pixelX, pixelY);
                    }
                    else
                    {
                        if (pixelX + ix >= 0 && pixelX + ix <= 255 && pixelY + iy >= 0 && pixelY + iy <= 255)
                        {
                            point = new Point(pixelX + ix, pixelY + iy);
                            borderPoint = (ix == -doublePixelSize) || (iy == -doublePixelSize) ||
                                              (ix == doublePixelSize) || (iy == doublePixelSize);
                        }
                        else
                        {
                            break;
                        }
                    }
                    HotSpot hotSpot;
                    if (hotSpots.ContainsKey(point))
                    {
                        hotSpot = hotSpots[point];
                        hotSpot.borderPoint &= borderPoint;
                        hotSpot.count += 1;
                    }
                    else
                    {
                        hotSpot = new HotSpot { borderPoint = borderPoint, count = 1 };
                        hotSpots.Add(point, hotSpot);
                    }
                    if (zoomLevel < doublePixelZoomLevel)
                    {
                        break;
                    }
                }
                if (zoomLevel < doublePixelZoomLevel)
                {
                    break;
                }
            }
        }
        foreach (var hotspotPixel in hotSpots)
        {
            double hc = hotspotPixel.Value.count;
            double hcDensity = hc / pixelArea;

            Color color;
            if (!hotspotPixel.Value.borderPoint)
            {
                color = Color.FromArgb(255, 255,
                                       (int)
                                       Math.Max((maxHotspotDensity - hcDensity) / maxHotspotDensity * 255, 0.0),
                                       0);
            }
            else
            {
                color = Color.Black;
            }
            bitmap.SetPixel(hotspotPixel.Key.X, hotspotPixel.Key.Y, color);
        }
        bitmap.Save(bitmapFileName);
    }

    WritePngToStream(bitmap, Response.OutputStream);
}
目前,我收到以下错误消息
A generic error occurred in GDI+.
说明:执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪,以获取有关错误及其在代码中起源的更多信息。 异常详细信息:System.Runtime.InteropServices.ExternalException:GDI +中发生一般错误。 源错误: 当前Web请求的执行期间生成了未处理的异常。可以使用下面的异常堆栈跟踪来标识有关异常的来源和位置的信息。 堆栈跟踪: [ExternalException(0x80004005):GDI +中发生一般错误。    System.Drawing.Image.Save(字符串文件名,ImageCodecInfo编码器,EncoderParameters编码器参数)+772265    C:\\ Projects \\ xxx \\ xxx \ SpeedPrap \\ HotSpotTileServer.aspx.cs:141中的HotSpotTileServer.Page_Load(Object sender,EventArgs e)    System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp,Object o,Object t,EventArgs e)+25    System.EventHandler.Invoke(对象发送方,EventArgs e)+0    System.Web.UI.Control.LoadRecursive()+71    System.Web.UI.Page.ProcessRequestMain(布尔includeStagesBeforeAsyncPoint,布尔includeStagesAfterAsyncPoint)+3048 版本信息:Microsoft .NET Framework版本:4.0.30319; ASP.NET版本:4.0.30319.1     
已邀请:
您可以尝试三种方法: 对于临时文件-不需要在Web服务器之间共享(这种情况很少见!)-那么您可以使用本地存储-http://vkreynin.wordpress.com/2010/01/10/learning-azure-我的本地存储/ 对于在Web服务器之间共享的磁盘(但其中只有一个具有写访问权),可以使用Azure驱动器-http://blog.maartenballiauw.be/post/2010/02/02/Using-Windows-Azure-Drive -(aka-X-Drive).aspx 对于常规的灵活共享文件存储,请尝试使用Azure Blob存储-http://blogs.msdn.com/b/jnak/archive/2008/10/29/walkthrough-simple-blob-storage-sample.aspx 绝对是我推荐的最后一个-它快速,灵活且可扩展。     
(我100%同意Stuart。)以下是我建议您考虑使用Azure Blob存储存储热图png文件的更多原因: 不保证本地硬盘具有持久性。 (但是,如果可以轻松地重新生成它们,这对您可能并不重要。) 可以使Blob公开可见(例如,可以使用img标签直接从HTML代码中引用它们)。 可以轻松地在AppFabric CDN中使用Blob(为了获得更好的性能,包括大约24个全球分发点)。 Blob将以使用本地文件系统不会的方式进行缩放。例如,如果您想扩展站点以使用多个Heatmap生成器角色实例(在云中的不同计算机上运行它们中的2个),则您将希望位于Blob存储上,因为其他任何选项均无效。 Blob针对云规模,可靠性和高可用性进行了优化。 我建议您使用非常方便的Windows Azure SDK来编写Blob。 SDK用一组非常好的类包装了官方的REST接口,这些类非常易于从.NET代码使用。具体来说,您将使用CloudBlobClient类和方法UploadByteArray。您可以在此处下载Azure SDK 1.4。     

要回复问题请先登录注册