Графика на Visual C++ и Java ч.1. Обработка изображений

Литература и ресурсы

WF-сети

Сеть Петри называется сетью потоков работ (Work Flow-сетью), если выполняются следующие условия:

· существует только одна исходная позиция i, такая что отсутствуют переходы входящие в i;

· существует только одна конечная позиция o, такая что отсутствуют переходы выходящие из o;

· каждый узел данной сети расположен на пути от i к о.

WF-сети используются для проверки графов потоков работ на наличие таких структурных конфликтов, как «тупики» (deadlocks) и «недостатки синхронизации» (lack of synchronization).

Структурные конфликты отсутствуют, если WF-сеть является бездефектной.


Свойство бездефектности или правильной завершаемости соответствует следующим требованиям:

· конечная позиция o достижима при любой последовательности переходов от позиции i;

· WF-сеть не содержит лишних переходов (которые никогда не будут выполнены);

· при достижении конечной позиции данной сети не должно оставаться фишек в промежуточных позициях.


1. Котов В.Е. Сети Петри. - М.: Наука, 1984. - 160 с

2. Д.Питерсон Теория сетей Петри и моделирование систем Пер. с анг. М.: МИР. 1984

3. https://www.informatik.uni-hamburg.de/TGI/PetriNets/
Petri Nets World - services for the international Petri Nets community

4. https://pipe2.sourceforge.net/
Platform Independent Petri net Editor - a tool for creating and analyzing Petri nets

Задачи обработки графики:

а) загрузка изображения из файла в требуемое место формы

с преобразованием (изменение размеров...), в том числе

и поверх существующего изображения.

б) преобразование загруженного изображения целиком по отдельным точкам

в) рисование по изображению различных геометрических фигур

г) сохранение изображения

1)Использование pictureBox ля работы с графикой в Visual C++.

Загрузка изображений

а)

Добавление pictureBox:

Отклик на событие Form1->Load:

private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e)

{

Work();

}

Функция Work после конструктора Form1:

Form1(void)

{

InitializeComponent();

//

//TODO: добавьте код конструктора

//

}

void Work()

{

Bitmap^ bmp = gcnew Bitmap(450,350); // битовая карта для закрепления к pictureBox

// размеры как у pictureBox

Graphics^ g = Graphics::FromImage(bmp); // холст для рисования

pictureBox1->Image = bmp; // закрепление к pictureBox

Bitmap^ image1; // фото загрузки в pictureBox

image1 = gcnew Bitmap("photo1.jpg"); // инициализация файл с фото

g->DrawImage(image1,10,20); // размещение фото left=10, top=20 в pictureBox

}

Вывод части рисунка:

Изменение Work – вывод рисунка в заданный прямоугольник:

void Work()

{

Bitmap^ bmp = gcnew Bitmap(450,350); // битовая карта для закрепления к pictureBox

// размеры как у pictureBox

Graphics^ g = Graphics::FromImage(bmp); // холст для рисования

pictureBox1->Image = bmp; // закрепление к pictureBox

Bitmap^ image1; // фото загрузки в pictureBox

image1 = gcnew Bitmap("photo1.jpg"); // инициализация sфайл с фото

Rectangle r;

double p;

r.X=10;

r.Y=20;

r.Width=300;

r.Height=100;

g->DrawImage(image1,r);

}

Вывод без сохранения соотношения сторон:

Корректировка – вычисление пропорциональной высоты прямоугольника:

#include <math.h>

......

void Work()

{

Bitmap^ bmp = gcnew Bitmap(450,350); // битовая карта для закрепления к pictureBox

// размеры как у pictureBox

Graphics^ g = Graphics::FromImage(bmp); // холст для рисования

pictureBox1->Image = bmp; // закрепление к pictureBox

Bitmap^ image1; // фото загрузки в pictureBox

image1 = gcnew Bitmap("photo1.jpg"); // инициализация sфайл с фото

Rectangle r;

double p;

int w,h;

w=image1->Width;

h=image1->Height;

r.X=10;

r.Y=20;

p=h;

r.Width=300;

r.Height=floor(p/w*r.Width);

g->DrawImage(image1,r);

}

Вывод в прямоугольник:

Модификация Work – вывод прямоугольной части второго изображения

поверх первого в заданный прямоугольник

void Work()

{

Bitmap^ bmp = gcnew Bitmap(450,350); // битовая карта для закрепления к pictureBox

// размеры как у pictureBox

Graphics^ g = Graphics::FromImage(bmp); // холст для рисования

pictureBox1->Image = bmp; // закрепление к pictureBox

Bitmap^ image1; // 1 фото загрузки в pictureBox

Bitmap^ image2; // 2 фото загрузки в pictureBox

image1 = gcnew Bitmap("photo1.jpg"); // инициализация sфайл с фото 1

image2 = gcnew Bitmap("photo2.jpg"); // файл с фото 2

Rectangle r;

double p;

int w,h;

w=image1->Width;

h=image1->Height;

r.X=10;

r.Y=20;

p=h;

r.Width=300;

r.Height=floor(p/w*r.Width);

g->DrawImage(image1,r); // вывод 1 фото в прямоугольник r

Rectangle r1; // прямоугольник исходного изображения,

// куда помещать второе

r1.X=200;

r1.Y=200;

p=h;

r1.Width=50;

r1.Height=floor(p/w*r1.Width);

Rectangle r2; // прямоугольник для части второго изображения

r2.X=2000;

r2.Y=1500;

r2.Width=2000;

r2.Height=floor(p/w*r2.Width);

GraphicsUnit u = GraphicsUnit::Pixel; // единицы измерения - пикселы

g->DrawImage(image2,r1,r2,u);

}

2)Использование JPanel для работы с графикой в Java SE.

Загрузка изображений

В java рисование происходит на компоненте и выполняет рисование

метод paintComponent. Для вывода изображений необходимо

перегрузить paintComponent.

Пример графики на SE:

Выводится изображение из файла в JPanel на форме

Вывод части рисунка:

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.image.BufferedImage;

import java.io.File;

import java.io.IOException;

import javax.imageio.ImageIO;

import javax.swing.JFrame;

import javax.swing.JPanel;

public class lab10

{

JFrame form;

pictureBox pc; // подкласс от JPanel

lab10()

{

form = new JFrame();

form.setBounds (10,20,500,500);

form.setTitle ("лабораторная 10");

form.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

form.setLayout(null);

pc=new pictureBox();

pc.setBounds(0, 0, 300, 300);

form.add(pc);

form.show();

}

public static void main (String args[])

{

lab10 f;

f= new lab10();

}

class pictureBox extends JPanel // наследник от JPanel

{

public BufferedImage im1; // image для загрузки 1 фото

public pictureBox ()

{

try

{

im1 = ImageIO.read(new File("photo1.jpg")); // чтение image из файла

}

catch (IOException e)

{

}

}

public void paintComponent(Graphics g) // метод рисования

{

g.drawImage(im1, 10, 20, null); // вывести часть изображения

repaint();

}

}

}

Вывод изображениея в заданный прямоугольник без сохранения пропорций

g.drawImage(im1, 10, 20,200,100, null);

вывод прямоугольной части второго изображения

поверх первого в заданный прямоугольник

class pictureBox extends JPanel // наследник от JPanel

{

public BufferedImage im1; // image для загрузки 1 фото

public BufferedImage im2; // image для загрузки 1 фото

public pictureBox ()

{

try

{

im1 = ImageIO.read(new File("photo1.jpg")); // чтение image из файла

}

catch (IOException e)

{

}

try

{

im1 = ImageIO.read(new File("photo2.jpg")); // чтение image из файла

}

catch (IOException e)

{

}

}

int w,h;

int wd,hd;

double p;

w=im1.getWidth(); // размер изображения

h=im1.getHeight();

wd=300; // ширина прямоугольника для вывода 1 фото

p=h;

hd=(int)Math.round(p/w*wd);

g.drawImage(im1, 10, 20,wd,hd, null); // вывод 1 фото

// в прямоугольник с сохранением пропорций

int dx1,dy1,dx2,dy2;

int sx1,sy1,sx2,sy2;

dx1=200;

dy1=200;

dx2=250;

p=h;

hd=(int)Math.round(p/w*(dx2-dx1));

dy2=dy1+hd; // dx1, dy1, dx2,dy2 верхний левый – правый нижний,

// куда вставлять.

sx1=2000;

sy1=1500;

sx2=4000;

hd=(int)Math.round(p/w*(sx2-sx1));

sy2=sy1+hd; // sx1, sy1, sx2,sy2 верхний левый – правый нижний,

// прямоугольник от вставляемого изображения

g.drawImage(im2,dx1,dy1,dx2,dy2,sx1,sy1,sx2,sy2, null);

3)Использование ресурсов в Java ME.

Ресурсы в Java – часть архива jar, которые содержат текстовые файлы,

графические, звуковые и т.д. Предназначены только для чтения и

служат частичной компенсацией отсутствия файловой системы.

Пример чтения текстового файла из ресурса.

В папку \MobileApplication1\src где находится программа

lab10.java добавить папку TextFiles, в ней создать файл test.txt

с тремя строками:

first

qwerty

В ресурсы приложения добавляется папка TextFiles

Файл test.txt дополнительно скопировать в корень приложения mobileapplication1

Чтение строк из файла ресурса и вывод их в label.

import javax.microedition.midlet.*;

import com.sun.lwuit.*;

import com.sun.lwuit.events.*;

import com.sun.lwuit.geom.*;

import com.sun.lwuit.layouts.*;

import java.io.InputStream;

import java.io.IOException;

public class lab10 extends MIDlet

{

Form form;

Label lb;

String [] Ac=new String[5]; // строки для чтения

public void startApp()

{

int w,h;

Dimension d=new Dimension(200,200);

Display.init(this);

form = new Form();

form.setPreferredSize(d); // пытаться установить 200x200,

form.setTitle("лабораторная 10 ч.1");

w=form.getWidth();

h=form.getHeight();

CoordinateLayout ee = new CoordinateLayout(w,h);

form.setLayout(ee);

// положение и надпись label

lb=new Label();

lb.setX(20); // слева 20

lb.setY(30); // сверху 30

lb.setText("тест строковых ресурсов");

form.addComponent(lb);

form.show();

InputStream is = getClass().getResourceAsStream("test.txt"); // поток ввода из ресурса

try

{

char ch=0;

int rd=0;

int i=0;

Ac[0]="";

while ((rd = is.read())!=-1) // чтение посимвольно

{

ch=(char)rd; // прочитанный символ

if(ch!= '\r')

Ac[i]=Ac[i]+ch;

else

{

rd = is.read(); // прочитать '\n'

i++;

Ac[i]=""; // следующая строка

}

}

}

catch (Exception e)

{

}

String s=new String();

s=Ac[0]+" "+Ac[1]+" "+Ac[2];

lb.setText(s);

}

public void pauseApp()

{

}

public void destroyApp(boolean unconditional)

{

}

}

4)Использование ресурсов для работы с графикой в Java ME.

Загрузка изображений

В папку \MobileApplication1\src где находится программа lab10.java

добавить папку, Images и в ней добавить два файла photo1.jpg, photo2.jpg,

затем к ресурсам добавить папку:

Изображение части рисунка на форме lwuit:

import javax.microedition.midlet.*;

import com.sun.lwuit.*;

import com.sun.lwuit.events.*;

import com.sun.lwuit.geom.*;

import com.sun.lwuit.layouts.*;

public class lab10 extends MIDlet

{

pictureBox form;

public void startApp()

{

int w,h;

Dimension d=new Dimension(200,200);

Display.init(this);

form = new pictureBox();

form.setPreferredSize(d);

w=form.getWidth();

h=form.getHeight();

CoordinateLayout ee = new CoordinateLayout(w,h);

form.setLayout(ee);

form.show();

}

public void pauseApp()

{

}

public void destroyApp(boolean unconditional)

{

}

class pictureBox extends Form // наследник form

{

public void paint(Graphics g)

{

Image im = null;

try

{

im=Image.createImage("/Images/photo1.jpg");

}

catch (Exception e)

{

}

g.drawImage(im, 0, 0);

}

}

}

Возможность рисования на форме ограничена, небольшое число

команд, нет возможности загрузки части изображения и т.д.

класс Canvas позволяет рисовать и обрабатывать изображения, но нет

label, textfield, button и т.д.

Вывод части изображения в canvas:

import javax.microedition.lcdui.Canvas;

import javax.microedition.lcdui.Display;

import javax.microedition.lcdui.Graphics;

import javax.microedition.lcdui.Image;

import javax.microedition.midlet.*;

public class lab10 extends MIDlet

{

private Display dsp;

private MyCanvas cv; // MyCanvas наследник Canvas

public void startApp()

{

cv= new MyCanvas();

dsp=Display.getDisplay(this);

dsp.setCurrent(cv); // вкючить display на Canvas

}

public void pauseApp()

{

}

public void destroyApp(boolean unconditional)

{

}

class MyCanvas extends Canvas

{

protected void paint(Graphics g) // перегрузка метода paint

{

Image im = null;

try

{

im=Image.createImage("/Images/photo1.jpg"); // из ресурсов

}

catch (Exception e)

{

}

g.drawImage(im, 10, 20, Graphics.LEFT | Graphics.TOP);

// left=10, top=20 выравнивать (якорь) по левому верхнему углу

}

}

}

Вывод части изображения в область, начинающуюся с

заданного верхнего угла:

g.drawRegion(im, 10, 20, 200, 150, 0, 15, 25,

Graphics.LEFT | Graphics.TOP);

Прямоугольная часть фотографии (left=10, top=20, width=200,

height=150) без преобразований (0 – без поворотов и зеркальных

отображений) выводится начиная с точки (left=15, top=25).

Вывод части второго изображения в область, начинающуюся с

заданного верхнего угла поверх первого:

protected void paint(Graphics g)

{

Image im1 = null;

Image im2 = null;

try

{

im1=Image.createImage("/Images/photo1.jpg"); // из ресурсов

im2=Image.createImage("/Images/photo2.jpg"); // из ресурсов

}

catch (Exception e)

{

}

g.drawImage(im1, 10, 20, Graphics.LEFT | Graphics.TOP);

g.drawRegion(im2, 330, 190, 70, 40, 0, 15, 270,

Graphics.LEFT | Graphics.TOP);

}

5) Обработка событий мыши для компонент

На Visual C++ MouseDown – событие, когда нажата кнопка мыши,

MouseMove – когда сместился курсор мыши

MouseUp – когда кнопка мыши отпущена

public ref class Form1: public System::Windows::Forms::Form

{

public:

int Regim; // режим работы мыши

int MouseX,MouseY,OldX,OldY; // координаты мыши

Form1(void)

..............................

void Work()

{

Regim=0; // нач. зачение

Дополнение - обработка событий мыши для pictureBox

private: System::Void pictureBox1_MouseDown(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e)

{

if(e->Button == System::Windows::Forms::MouseButtons::Left)

// right – правая кнопка

{

OldX=e->X; // начальные координаты

OldY=e->Y;

MouseX=OldX; // текущие координаты

MouseY=OldY;

Regim=1; // клавиша нажата

}

}

private: System::Void pictureBox1_MouseMove(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e)

{

if(Regim==1)

{

// новые текущие координаты

MouseX=e->X;

MouseY=e->Y;

}

}

private: System::Void pictureBox1_MouseUp(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e)

{

if(Regim==1)

{

MouseX=e->X;

MouseY=e->Y;

Regim=0; // клавиша отпущена

// выделен прямоугольник OldX,OldY, MouseX,MouseY

}

}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: