Спонсор: Microsoft
Опубликован: 24.05.2010 | Уровень: специалист | Доступ: платный
Самостоятельная работа 4:

Работа с изображениями в ASP.Net

Поддерживаемые форматы изображений

GDI+ поддерживает достаточно много форматов изображений, включая самые распространенные из них: JPEG, GIF, BMP и PNG. Полный набор форматов изображений содержится в структуре ImageFormat. Находящийся в памяти объект Bitmap можно сохранить в любом поддерживаемом формате, используя одну из перегруженных версий метода Save:

bmp.Save(outputStream, ImageFormat.Gif);

Когда вы пытаетесь записать изображение в выходной поток или дисковый файл, система ищет кодер для запрошенного формата. Этим кодером является модуль GDI+, преобразующий данные в указанный формат. Учтите, что кодер реализован в виде неуправляемого кода, функционирующего на платформе Win32. Как правило, кодер позволяет задать не только формат данных, но и дополнительные установки, такие, например, как степень сжатия изображения JPEG.

Создание круговой диаграммы

Проще всего рассмотреть создание круговой диаграммы на конкретном примере:

namespace SMPA
{
  public partial class Diagram : System.Web.UI.Page
  {

    public void ProcessRequest(HttpContext context)
    {
      object o = context.Request["url"];
      if (o == null)
      {
        context.Response.Write("No image found");
        context.Response.End();
        return;
      }
      string file = context.Server.MapPath((string)o);
      if (File.Exists(file))
      {
        Bitmap bmp = draw();
        context.Response.ContentType = "image/jpeg";
        bmp.Save(context.Response.OutputStream, ImageFormat.Jpeg);
        bmp.Dispose();
      }
      else
      {
        context.Response.Write("No image found");
        context.Response.End();
       }
     }

    //Приступаем к непосредственному созданию диаграммы           
    Bitmap draw()
    {

      string strTypesLegend = "";
      string strTestsData = "";
      //В данном пример данные для диаграммы передаются через сессии
      //и представляют собой две строки, в которых значения раздеены запятыми
      strTypesLegend = (string)Session["map"];
      strTestsData = (string)Session["data"];
      //формируем массивы исходных данных
      char[] str = strTestsData.ToCharArray();
      int length = strTestsData.Length;
      int size = 1;

      for (int i = 0; i < length; ++i)
      {
        if (str[i] == ',') { ++size; }
      }

      float[] data = new float[size];
      string d1 = "";
      int j = 0;
      float sum = 0;
      for (int i = 0; i < length; ++i)
      {
        if ((str[i] != ',') & (i != length - 1)) { d1 += str[i]; }
        else
        {
          if (i == length - 1) { d1 += str[i]; }
          data[j] = Convert.ToInt64(d1);
          d1 = "";
          sum += data[j];
          ++j;
        }
      }
      //
      //массив исходных данных легенды диаграммы
      int leglength = strTypesLegend.Length;
      char[] chr = strTypesLegend.ToCharArray();
      string[] legend = new string[size];
      j = 0;
      for (int i = 0; i < leglength; ++i)
      {
        if ((chr[i] != ',') & (i != leglength)) { d1 += chr[i]; }
        else
        {
          legend[j] = "" + d1;
          d1 = "";
          ++j;
        }
        if (i == leglength - 1) { legend[j] = "" + d1; };
      }
      //

      // Для упрощения и большей наглядности, было решено выводить только 10 
     //значений данных, 9 наибольших и 1 - для всех оставшихся значений
      if (size > 10)
      {
        float sumoth = 0;
        for (int i = 9; i < size; i++)
        {
          sumoth += data[i];
        }
        data[9] = sumoth;
        legend[9] = "other";
        size = 10;
      }
      //

      Bitmap bmp = new Bitmap(500, 250);
      Graphics g = Graphics.FromImage(bmp);
      //задаем цвета секторов диаграммы
      Color[] clr = new Color[10];
      clr[0] = Color.Red;
      clr[1] = Color.Blue;
      clr[2] = Color.Violet;
      clr[3] = Color.Green;
      clr[4] = Color.Gray;
      clr[5] = Color.Chocolate;
      clr[6] = Color.Coral;
      clr[7] = Color.Indigo;
      clr[8] = Color.GreenYellow;
      clr[9] = Color.Khaki;
      float startAngle = 0;
      g.Clear(Color.White);
      StringFormat sf = new StringFormat();
      sf.Alignment = StringAlignment.Near;
      sf.LineAlignment = StringAlignment.Near;
      Font f = new Font("Times New Roman", 10);

      StringFormat sfr = new StringFormat();
      sfr.Alignment = StringAlignment.Near; ;
      sfr.LineAlignment = StringAlignment.Near;
      int t = 0;
      //Рисуем сегменты
      for (int counter = 8; counter > 0; --counter )
        for (int i = 0; i < size; ++i)
        {
          double dt = data[i] * 360 / sum;
          double prcnt = data[i] / sum * 100;
          //вычисляем угол очередного сегмента
          float sweepAngle = Convert.ToInt64(Math.Round(dt));

          Rectangle rect1 = new Rectangle(/*20-counter*/0, 2*counter, 250, 150);
          if (counter == 1)
          {
            g.FillPie(new SolidBrush(clr[i]), rect1, startAngle, sweepAngle);
          }
          else
          {
            g.FillPie(new HatchBrush(HatchStyle.Percent50, Color.Black, clr[i]),
            rect1, startAngle, sweepAngle);
          }
          
          if ((counter == 8) || (counter == 1))
          {
            g.DrawEllipse(new Pen(Color.Black, 1), rect1);
          }
          startAngle += sweepAngle;
          //Отрисовка легенды
          Rectangle rec = new Rectangle(280, i * 20, 250, 50);
          g.FillRectangle(new SolidBrush(clr[i]), new Rectangle(260,i*20,10,10));
          g.DrawString(legend[i] + " - " +data[i]+" ("+ 
                        Math.Round(prcnt, 2) + "%)", 
                       f, new SolidBrush(Color.Black), rec, sf);

        }            
        return bmp;
      }
    }
  }

Примеры диаграмм, сформированных на основе данного кода:


Екатерина Соколова
Екатерина Соколова
Россия, Ухта
Никита Гекторов
Никита Гекторов
Украина, Донецк