Добавление фонового рисунка в изображение обработчика http - PullRequest
0 голосов
/ 19 ноября 2010

следующий код - это обработчик, который принимает проценты (проценты на графике, отображаемые синим цветом), макс (максимальное значение) и значение (число) в галлонах для создания индикатора хода в стиле термометра.Он выводит график, который добавляется в веб-форму как <img src="Thermometer.ashx" alt="" />.

Поскольку этот график предназначен для отображения прогресса в виде количества сэкономленных литров воды, было бы неплохо, чтобы синий цвет заполнял изображение бочки с водой.Для этого я попытался добавить изображение бочонка с прозрачной внутренней частью к веб-форме и попытался расположить его перед изображением термометра, но это не сработало, поскольку кажется невозможным наложить изображение поверх изображения, созданного с использованиемобработчик.

У меня такой вопрос: возможно ли добавить изображение бочки через код, чтобы он служил контуром для синего термометра?Или изображение бочки нужно создавать с нуля в коде?Я боюсь последнего, так как я, вероятно, не могу его кодировать.

Пожалуйста, посмотрите ниже и дайте мне знать, если я могу что-нибудь сделать.

Спасибо!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Drawing;
using System.Net;
using System.Drawing.Imaging;
using System.Web.UI.HtmlControls;
namespace rainbarrel
{
    public class Thermometer : IHttpHandler
    {
        public bool IsReusable
        {
            get { return false; }
        }

        public void ProcessRequest(HttpContext context)
        {
            int Percent = 25;
            int Max = 20000;
            bool Gallon = true; 
            float Pixels = (float)Percent * 2.15f;
            Bitmap TempImage = new Bitmap(200, 250);
            Graphics TempGraphics = Graphics.FromImage(TempImage);
            TempGraphics.FillRectangle(Brushes.White, new Rectangle(0, 0, 200, 250));
            Pen TempPen = new Pen(Color.Black);
            BarrelFill(TempImage, Percent);
            bool DrawText = true;
            float Amount = Max;
            for (float y = 20.0f; y < 235.0f; y += 10.75f)
            {
                TempGraphics.DrawLine(TempPen, 119, y, 125, y);
                if (DrawText)
                {
                    Font TempFont = new Font("Arial", 8.0f, FontStyle.Regular);
                    if (Gallon)
                    {
                        TempGraphics.DrawString(Amount.ToString() + " Gal", TempFont, Brushes.Black, 130, y);
                    }
                    else
                    {
                        TempGraphics.DrawString(Amount.ToString(), TempFont, Brushes.Black, 130, y);
                    }
                    DrawText = false;
                }
                else DrawText = true;
                Amount -= ((Max / 100) * 5.0f);
            }

            string etag = "\"" + Percent.GetHashCode() + "\"";
            string incomingEtag = context.Request.Headers["If-None-Match"];

            context.Response.Cache.SetExpires(DateTime.Now.ToUniversalTime().AddDays(1));
            context.Response.Cache.SetCacheability(HttpCacheability.Public);
            context.Response.Cache.SetMaxAge(new TimeSpan(7, 0, 0, 0));
            context.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
            context.Response.Cache.SetETag(etag);

            if (String.Compare(incomingEtag, etag) == 0)
            {
                context.Response.StatusCode = (int)HttpStatusCode.NotModified;
                context.Response.End();
            }
            else
            {
                context.Response.ContentType = "image/Gif";
                TempImage.Save(context.Response.OutputStream, ImageFormat.Gif);
                TempImage.MakeTransparent();
            }
        }

        private void BarrelFill(Bitmap TempImage, int Percent)
        {
            if (Percent == 100)
            {
                FillRectangle(TempImage, 60, 20, 235);
            }
            else
            {
                FillRectangle(TempImage, 60, (int)(235.0f - ((float)Percent * 2.15f)), 235);
            }
        }

        private void FillRectangle(Bitmap TempImage, int x, int y1, int y2)
        {
            int MaxDistance = 50;
            for (int i = x - MaxDistance; i < x + MaxDistance; ++i)
            {
                for (int j = y1; j < y2; ++j)
                {
                    float Distance = (float)Math.Abs((i - x));
                    int BlueColor = (int)(255.0f * (1.0 - (Distance / (2.0f * MaxDistance))));
                    TempImage.SetPixel(i, j, Color.FromArgb(30, 144, BlueColor));
                }
            }
        }
    } 
}

ОБНОВЛЕНИЕ:

Я нашел этот пост здесь, который показал мне, как решить: наложение изображений сGDI +

Вот мое решение:

Image Barrel = Image.FromFile("C:\\Inetpub\\wwwroot\\barrel\\barrel_trans.png");
            TempGraphics.DrawImage(Barrel, -5, 0, 120, 240);
            Barrel.Dispose();

Однако качество слоя png плохое (слегка размытое), хотя оригинал очень резкий и четкий.Есть ли способ сохранить качество изображения оригинала?

Большое спасибо заранее за вашу помощь.

Ответы [ 2 ]

0 голосов
/ 20 ноября 2010

Я считаю, что лучший способ сделать это - создать полное изображение в C # и отправить его вниз. Вы можете получить точное позиционирование ствола над «термометром», и если ствол уже (полу) прозрачный PNG, вы можете просто сделать .DrawImage прямо над термостатом, добавить текст и сделать все, что вы хотите, прежде чем отправить обратно окончательное изображение прямо в ResponseStream.

Несколько других предложений для вас:

Поскольку вы передаете все непосредственно в свой обработчик, вы должны распоряжаться своими собственными внутренними одноразовыми ресурсами. «Использование» блоков - самый простой способ. Вам понадобятся как минимум эти два:

using (Graphics TempGraphics = GetGraphicsFromBitmap(TempImage))
{
    for (float y = 20.0f; y < 235.0f; y += 10.75f)
    {
        TempGraphics.DrawLine(TempPen, 119, y, 125, y);
        ...
    }
}

и

using (Font TempFont = new Font("Arial", 8.0f, FontStyle.Regular))
{
    ...
}
0 голосов
/ 20 ноября 2010

Изменение TempImage.Save(context.Response.OutputStream, ImageFormat.gif); на Jpeg решило проблему качества.

...