Опубликован: 24.05.2010 | Доступ: свободный | Студентов: 1151 / 67 | Оценка: 3.70 / 3.05 | Длительность: 21:19:00
Самостоятельная работа 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+ гораздо, шире, чем мы здесь описали, они отнюдь не ограничены выполнением нескольких простых операций. Однако полное рассмотрение функций этой системы выходит за рамки данной книги.