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

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

Аннотация: В рамках данного практического занятия вы ознакомитесь с основами работы с изображениями в asp.net, также будет рассмотрен пример динамического создания круговой диаграммы.

Доступ к изображениям с веб - страниц

HTML-тэг <img> используется для вывода изображения на Web-странице. Он поддерживает несколько атрибутов, с помощью которых задается ширина, высота изображения и альтернативный текст, выводимый, когда оно не доступно. HTML-определение этого элемента таково:

<img id="control ID" alt="alternate text"
align="top | middle | bottom | left | right" border="border width" height="height" src="URL"
width=" width" />

В Visual Studio имеется два серверных элемента управления для размещения изображений на веб - странице: Image и ImageButton.На панели свойств этих ЭУ можно указать URL изображения и задать прочие параметры (размер изображения, ID ЭУ и пр.)

Отличие Image от ImageButton заключается в том, что у ImageButton присутствует событие Click.


Доступ к изображениям, хранящимся в базе данных

Вопрос о целесообразности применения баз данных для хранения изображений является спорным. Одни специалисты считают такое решение вполне эффективным, другие говорят, что никогда не делали этого и не будут делать. Как бы там ни было, фактом остается то, что все популярные СУБД уже давным-давно поддерживают большие двоичные объекты — BLOB (binary large objects).

BLOB (англ. Binary Large OBject — двоичный большой объект) — массив двоичных данных. В СУБД BLOBспециальный тип данных, предназначенный, в первую очередь, для хранения изображений, аудио и видео, а также компилированного программного кода.

Загрузка В БД

// Показываем диалог выбора файла 
openFileDialog1.ShowDialog(); 
// В качестве имени сохраняемого файла устанавлиываем переменную fileName 
string fileName = openFileDialog1.FileName; 

Byte[] blob;// = null; 
using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read)) 
{ 
blob = new Byte[fileStream.Length]; 
fileStream.Read(blob, 0, blob.Length); 
} 

string commandText = "INSERT INTO table1 (name, rtf) VALUES(@name, @rtf)"; 
myCommand.Connection = conn; 
myCommand.CommandText = commandText; 

OleDbDataAdapter dataAdapter = new OleDbDataAdapter(); 
dataAdapter.InsertCommand = myCommand; 
myCommand.Parameters.Add("@name", OleDbType.VarChar, 50).Value = "Дима"; 
myCommand.Parameters.Add("@rtf", OleDbType.Binary, blob.Length).Value = blob; 


DataSet ds = new DataSet(); 

dataAdapter.TableMappings.Add("Table", "table1"); 
//dataAdapter.Fill(ds); 

conn.Open(); 
myCommand.ExecuteNonQuery(); 
conn.Close();

\

Чтение изображения из базы

//Показываем диалог выбора файла 
saveFileDialog1.ShowDialog(); 
// В качестве имени сохраняемого файла устанавлиываем переменную fileName 
string fileName = saveFileDialog1.FileName; 
//Создаем поток fs и открываем файл для записи. 
FileStream filestream = File.Open(fileName, FileMode.Create, FileAccess.Write); 
//Проверяем, открыт ли поток, и если открыт, выполняем условие 
if (filestream != null) 
{ 
//Создаем объект streamwriter и связываем его с потоком filestream 
StreamWriter streamwriter = new StreamWriter(filestream); 
//Записываем данные из TextBox в файл 


OleDbDataReader reader = myCommand.ExecuteReader(); 
BinaryWriter bw = new BinaryWriter(filestream); 

int bufferSize = 1024 * 1024 * 9; 
byte[] buffer = new byte[bufferSize]; 
reader.Read(); 
long startIndex = 0; 
int columnIdx = 2; 
long retval = reader.GetBytes(columnIdx, startIndex, buffer, 0, bufferSize); 
while (retval == bufferSize) 
{ 
bw.Write(buffer); 
bw.Flush(); 

startIndex += bufferSize; 
retval = reader.GetBytes(columnIdx, startIndex, buffer, 0, bufferSize); 
} 
bw.Write(buffer, 0, (int)retval); 
bw.Flush(); 



streamwriter.Write(buffer); 
//Переносим данные из потока в файл 
streamwriter.Flush(); 
//Закрываем поток 
filestream.Close(); 
} 
reader.Close(); conn.Close(); 

richTextRTF.LoadFile("Имя_Файла.rtf");

Динамическое генерирование изображений

Краткий обзор классов GDI+

GDI+ — это графическое ядро Microsoft Windows ХР, доступное и для других 32-и 64-разрядных платформ, в частности Windows 2000 и Windows 2003. Система GDI+, как следует из ее имени, является наследницей всем известной GDI (Graphics Device Interfaceинтерфейс графических устройств), входившей в состав предыдущих версий операционной системы Windows. .NET Framework инкапсулирует ключевые функции GDI+ в наборе управляемых классов и делает их доступными для приложений Web, Windows Forms и Web-сервисов.

Большую часть сервисов GDI+ можно отнести к одной из двух категорий: двумерная векторная графика и операции с изображениями. К первой относятся средства рисования простых фигур, таких как линии, кривые и многоугольники; что касается второй категории, то сюда относятся функции для вывода растровых и векторных изображений, манипулирования ими, их сохранения и преобразования. Есть еще и функции, принадлежащие к третьей категории, — типографические; они обеспечивают вывод текста различными шрифтами.

Имея в виду динамическое создание изображений на Web-сервере, мы сосредоточимся на рисовании фигур и текста, а также сохранении результатов в файлах формата JPEG или GIF.

Класс Graphics

Центральным элементом модели программирования Win32 GDI является контекст устройства. Так называется структура данных, используемая для хранения информации о возможностях конкретного устройства отображения. Контекст устройства ассоциируется с поверхностью для рисования, такой как окно, бумага в принтере или блок памяти. Программы Win32 получают дескриптор контекста устройства и передают его всем вызываемым функциям GDI. В составе контекста устройства поддерживается список установленных графических атрибутов — цвета фона и рисования, кисть, перо и шрифт. Можно сказать, что контекст устройства является связующим звеном между высокоуровневым API и драйверами устройств.

Класс Bitmap

Класс Bitmap инкапсулирует растровое изображение GDI+, он содержит пикселы самого изображения плюс несколько атрибутов. В GDI+ поддерживается три типа растровых изображений — битовые карты, значки и метафайлы. Все три соответствующих класса являются производными от абстрактного класса Bitmap. Заметьте, что экземпляр класса Bitmap вовсе не обязательно представляет файл с расширением .bmp; это универсальный контейнер пиксельных данных, которые можно сохранить в виде изображения формата BMP или JPG, — как вы сочтете нужным.

Заполнение прямоугольников

Для создания заполненного прямоугольника вам потребуется указать лишь вид кисти и размеры прямоугольника. Метод, которым вы будете пользоваться, называется FillRectangle, а рабочую область для него можно задать либо непосредственно в виде координат, либо с использованием структуры RectangleF:

g.FillRectangle(brush, area);

В данном вызове brush — это объект-кисть, используемый для рисования прямоугольника. GDI+ поддерживает множество разных видов кисти, в том числе сплошную, градиентную и текстурную. Следующий код показывает, как можно нарисовать и заполнить прямоугольник:

// Рисуем границу
Pen р = new Pen(Color.Black);
g.DrawRectangle(p, 0, 0, width, height);

// Заполняем
Brush brlnterior = new SolidBrush(Color.SkyBlue); 
g.FillRectangle(brInterior, 1, 1, width-2, height-2);

Рисование текста

Метод DrawString объекта Graphics принимает текстовую строку, которую ему нужно вывести, объект, представляющий шрифт, и кисть, которой этот текст будет нарисован. Кроме того, вы можете задать прямоугольник, в который необходимо вписать текст, способ выравнивания (по вертикали или по горизонтали) и указать, что делать, если текст не поместится в заданную область, — обрезать его или выйти за пределы области. Воспользовавшись структурой StringFormat, можно задать все эти параметры одновременно.

StringFormat sf = new StringFormat(); 
sf.Alignment = StringAlignment.Center; 
sf.LineAlignment = StringAlignment.Center;

// Рисуем текст
Font f = new Font('Tahoma", 16);
g.DrawString("Hello, world", f, 
                new SolidBrush(Color.White), 
                new Rectangle(0, 0, width, height), sf);

Возможности GDI+ гораздо, шире, чем мы здесь описали, они отнюдь не ограничены выполнением нескольких простых операций. Однако полное рассмотрение функций этой системы выходит за рамки данной книги.

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