Вступление
Примеры Словарь Вопросы
Sun Microsystems

Примеры программирования на Java

Регулировка изображения
(image.java)

Описание апплета
Пример работы апплета
//******************************************************************************
//
// ImageView.java:	Applet - изменение параметров изображения - яркость, контрастность,
//							 цветность, цветовые тона
//
//******************************************************************************

import java.applet.*;
import java.awt.*;
import java.awt.image.*;
import java.util.StringTokenizer;



//==============================================================================
// Основной класс - апплет ImageView
//
//==============================================================================
public class ImageView extends Applet implements Runnable
{
	private Image     m_imgOriginal = null; //оригинальное изображение
	private ImgFilter m_Filter  	= null; //фильтр изображения
	private ImageDraw m_ImageDraw	= null; //вспомогательный объект для рисования изображения
	private MediaTracker m_Tracker  = null; //вспомогательный объект для отслеживания загрузки изображения
	private Thread       m_Thread   = null; //нить ожидания загрузки изображения
		
	
	//имена изображений для иконок 
	private final String   m_sIco[] = { "bright.gif", "contr.gif", "saturat.gif",
	                                    "red.gif",    "green.gif", "blue.gif" };	

   	//контролы - текстовые поля  для ввода параметров
	private TextField m_editBr;   
	private TextField m_editContr;
	private TextField m_editSat;  
	private TextField m_editRed;  
	private TextField m_editGreen;  
	private TextField m_editBlue;  

	//кнопки
	private Button    m_btnReset; 
	private Button    m_btnApply; 
	
    // Члены класса - параметры 
    //--------------------------------------------------------------------------
	private String  m_sPict = "test.jpg";  //имя изображения
	private Color   m_clrBk = Color.white; //цвет фона
	private boolean m_fShowCtrls  = true;  //наличие контролов
    private boolean m_fFrame	  = true;  //наличие рамки вокруг аплета	 
	private boolean m_fLoadingBits   = false; //true, если апплет загружает изображение и еще не получил его первые биты
	private boolean	m_fFiltering  = false; //true, если апплет фильтрует изображение

	//имена параметров
	private final String PARAM_Picture = "Picture";
	private final String PARAM_Brightness = "Brightness";
	private final String PARAM_Contrast = "Contrast";
	private final String PARAM_Saturation = "Saturation";
	private final String PARAM_Red = "Red";
	private final String PARAM_Green = "Green";
	private final String PARAM_Blue = "Blue";
	private final String PARAM_Controls = "Controls";
	private final String PARAM_Frame = "Frame";
	private final String PARAM_BkColor = "BkColor";

	//размеры контролов и отступы
	final int nCtrlLeft   = 5;
	final int nCtrlTop    = 5;
	final int nCtrlGap    = 5;
	int	  m_nCtrlWidth  = 50;
	int	  m_nCtrlHeight = 20;

	// размеры поля контролов
	int m_nDimCtrlsX = 60;
	int m_nDimCtrlsY = 200;

	//размеры иконок
	final int nIcoWidth   = 15;
	final int nIcoHeight  = 15;

	// ImageView конструктор, создает члены объекта 
	//--------------------------------------------------------------------------
	public ImageView()
	{
		  //вспомогательный объект для рисования изображения		
		  m_ImageDraw = new ImageDraw(this, true);

		  //текстовые поля для ввода параметров	
		  m_editBr    = new TextField();
		  m_editContr = new TextField();
		  m_editSat   = new TextField();
  		  m_editRed   = new TextField();
		  m_editGreen = new TextField();
		  m_editBlue  = new TextField();

		  //кнопки	
		  m_btnReset  = new Button("Reset");
		  m_btnApply  = new Button("Apply");

		  //фильтр изображения
		  m_Filter	  = new ImgFilter();	

		  //вспомогательный объект для отслеживания загрузки изображения
		  m_Tracker   = new MediaTracker(this);
	}

	 
	public String[][] getParameterInfo()
	{
		String[][] info =
		{
			{ PARAM_Picture, "String", "Image for viewing" },
			{ PARAM_Brightness, "int", "Intial brightnes" },
			{ PARAM_Contrast, "int", "Initial contrast" },
			{ PARAM_Saturation, "int", "Inital saturation" },
			{ PARAM_Red, "int", "Initial red factor" },
			{ PARAM_Green, "int", "Initial green factor" },
			{ PARAM_Blue, "int", "Initial blue factor" },
			{ PARAM_Controls, "boolean", "Optional controls" },
			{ PARAM_Frame, "boolean", "Optional frame" },
			{ PARAM_BkColor, "String", "Background color"}
		};
		return info;		
	}

	// В методе init() происходит первичная инициализация апплета,
	// получение значений параметров и добавление контролов
	//--------------------------------------------------------------------------

	public void init()
	{
		//	Получение значений параметров и запоминание их в членах класса
		//----------------------------------------------------------------------
		String param;

		//имя изображения
		param = getParameter(PARAM_Picture);
		if (param != null)
			m_sPict = param;

		//яркость
		param = getParameter(PARAM_Brightness);
		if (param != null)
			m_Filter.setBr(Integer.parseInt(param));

		//контраст
		param = getParameter(PARAM_Contrast);
		if (param != null)
			m_Filter.setContr(Integer.parseInt(param));

		//насыщенность
		param = getParameter(PARAM_Saturation);
		if (param != null)
			m_Filter.setSat(Integer.parseInt(param));

		//фактор красного
		param = getParameter(PARAM_Red);
		if (param != null)
			m_Filter.setRed(Integer.parseInt(param));

		//фактор зеленого
		param = getParameter(PARAM_Green);
		if (param != null)
			m_Filter.setGreen(Integer.parseInt(param));

		//фактор синего
		param = getParameter(PARAM_Blue);
		if (param != null)
			m_Filter.setBlue(Integer.parseInt(param));

		//наличие контролов
		param = getParameter(PARAM_Controls);
		if (param != null)
			m_fShowCtrls = Boolean.valueOf(param).booleanValue();

		//наличие рамки вокруг аплета	 
		param = getParameter(PARAM_Frame);
		if (param != null)
			m_fFrame = Boolean.valueOf(param).booleanValue();
		
		//цвет фона
		param = getParameter(PARAM_BkColor);
		if (param != null)
		{
			//разбор строки цвета фона в форме "r,g,b" 
			StringTokenizer st = new  StringTokenizer(param, ",.");
			if( st.countTokens() == 3 )
			{
				int nRed   = Integer.parseInt(st.nextToken());
				int nGreen = Integer.parseInt(st.nextToken());
				int nBlue  = Integer.parseInt(st.nextToken());
				m_clrBk    = new Color(nRed, nGreen, nBlue);
			}
		}
		//установить цвет фона апплета
		setBackground(m_clrBk);
		
		//добавить контролы в контейнер
		if( m_fShowCtrls )
		{
			
			setLayout (null);
			//инициировать контролы значениями по умолчанию
			setControlsData();

			//добавление текстовых полей
			add (m_editBr);    
			add (m_editContr); 
			add (m_editSat);   
			add (m_editRed);   
			add (m_editGreen); 
			add (m_editBlue);  

			//создание и загрузка 6 иконок
			for( int i = 0; i<6; i++)
			{
				ImageDraw Ico = new ImageDraw();
				Ico.m_img = getImage(getDocumentBase(), m_sIco[i]);
				//Tracker будет ждать загрузки изображений иконок
				m_Tracker.addImage(Ico.m_img, 1);
				//установить цвет фона иконок
				Ico.setBackground(m_clrBk);
				add(Ico);
			}

			//добавление кнопок
			add (m_btnReset); 
			add (m_btnApply); 

			//вычислить размеры контролов на основе параметров шрифта
			FontMetrics fm = getFontMetrics(m_editBr.getFont());
			m_nCtrlHeight = fm.getAscent() + fm.getDescent();
			m_nCtrlHeight = fm.stringWidth(" Reset ");
			m_nDimCtrlsX  = m_nCtrlWidth + nCtrlLeft * 2;
			m_nDimCtrlsY  = (m_nCtrlHeight + nCtrlGap) * 8 + nCtrlTop;
		}
		//компонент для рисования изображения
		add (m_ImageDraw);
		m_ImageDraw.setBackground(m_clrBk);
	}

	
	// Метод  resize вызывается системой каждый раз при изменении размеров 
	// апплета. При изменении размеров переразмещаем контролы с помощью reshapeAll
	//--------------------------------------------------------------------------
	public void resize(int width, int height)
	{
		super.resize(width, height);
		reshapeAll(size().width, size().height);
	}

	// Метод reshapeAll размещает контролы в соответствии
	// c размерами апплета
	//----------------------------------------------------------
	private void reshapeAll(int width, int height)
	{
		int x = 0;
		int y = 0;

		int nW  = width;
		int nH  = height;

		if( m_fFrame ) 
		{
		 //выделяем по 2 пиксела с каждой стороны для рамки 
		 x+=2; nW -=4; 
		 y+=2; nH -=4; 
		}

		if( m_fShowCtrls  )
		{
			int nXCtrl = x; 
			int nYCtrl = y;

			if( m_fFrame )
			{
				//если есть рамка - размещаем контролы с отступом от края
				nXCtrl += nCtrlLeft;
				nYCtrl += nCtrlTop;
			}	
			
			//ширина текстового поля меньше на размер иконки
			int nEditWidth = m_nCtrlWidth - nIcoWidth - 2;

			//переразмещаем текстовые поля и иконки слева от них
			if( countComponents() > 12 )
			{
				for( int i=0 ; i<6 ; i++)
				{
					getComponent(i).reshape(nXCtrl + nIcoWidth + 2, nYCtrl, nEditWidth, m_nCtrlHeight);
					getComponent(i+6).reshape(nXCtrl, nYCtrl + 2, nIcoWidth, nIcoHeight);
					nYCtrl += m_nCtrlHeight + nCtrlGap;
				}
			}
		
			//размещаем кнопки
			nYCtrl += nCtrlGap;
			m_btnApply.reshape(nXCtrl, nYCtrl, m_nCtrlWidth, m_nCtrlHeight); 
			nYCtrl += m_nCtrlHeight + nCtrlGap;
			m_btnReset.reshape(nXCtrl, nYCtrl, m_nCtrlWidth, m_nCtrlHeight); 
						
			nW  -= m_nDimCtrlsX;
			x	+= m_nDimCtrlsX;
		}
		//на оставшемся поле размещаем изображение
		m_ImageDraw.reshape( x, y, nW, nH);
	}

   	// Paint - рисуем рамку вокруг апплета, если задан этот параметр
	//--------------------------------------------------------------------------
	public void paint(Graphics g)
	{
		if( m_fFrame )
		{
			g.setColor(m_clrBk);
			g.draw3DRect(0, 0, size().width-1, size().height-1, true);
		}
	}

	// Запуск апплета - загружаем изображение для обработки и 
	// запускаем нить (thread), которая ждет полной загрузки 
	// изображения с помощью MediaTracker
	//--------------------------------------------------------------------------
	public void start()
	{
		m_fLoadingBits    = true;
		m_ImageDraw.m_img = m_imgOriginal = getImage(getDocumentBase(), m_sPict);
		
		if( m_fShowCtrls )
		{
			m_Tracker.addImage(m_ImageDraw.m_img, 1);
			m_Thread = new Thread(this);
			m_Thread.start();
		}
	}

	// Нить ожидания загрузки изображений с помощью m_Tracker. 
	//--------------------------------------------------------------------------
	public void run()
	{
		try
		{
			m_Tracker.waitForAll();
		}
		catch (InterruptedException e)
		{

		}
		
		// после того как все изображения загружены и компоненты созданы,
		// перерисовываем иконки.
		if( countComponents() > 12 )
		{
			for( int i=6 ; i<12 ; i++)
			{
				getComponent(i).repaint();
			}
		}
	}

	// Метод stop() - останавливаем выполнение нити Thread
	//--------------------------------------------------------------------------
	public void stop()
	{
		if( m_Thread != null )
			m_Thread.stop();
	}

	// imageUpdate - если получены первые биты изображения и необходимо фильтрование,
	// то накладываем фильтр на изображение
	//--------------------------------------------------------------------------
	public boolean imageUpdate(Image  img, int  infoflags, int  x, int  y, int w, int  h)
	{
		if( m_fLoadingBits )
		{
			if( (infoflags & ImageObserver.SOMEBITS) != 0 )
			{
				m_fLoadingBits    = false;
								
				if( !m_fFiltering && 
					(m_Filter.getBr() != 0  || m_Filter.getContr() !=0 || m_Filter.getSat() != 0 ||
					 m_Filter.getRed() != 0 || m_Filter.getBlue() !=0  || m_Filter.getGreen() != 0) ) 
				{
					doFilter();
				}
			}
		}
		else
		{	//если отрисовано все изображение, сбрасываем флаг фильтрации
			if( (infoflags & ImageObserver.ALLBITS) != 0 )
				 m_fFiltering = false;

		}
		return true;
	}

	// action вызывается системой при возникновении событий. Мы реагируем
	// на нажатие кнопок 'Apply' и 'Reset'.
	//------------------------------------------------------------------------
	public boolean action(Event e, Object o)
	{
		if( e.target instanceof Button )
		{
			// Нажата кнопка 'Apply'
			if( e.target == m_btnApply )
			{
				if( m_fFiltering == false ) //запрещаем повторный вход в фильтр
				{
					// Взять значения параметров из контролов 
					getControlsData();
					// Применить фильтр
					doFilter();
					// Перерисовать изображение
					m_ImageDraw.repaint();
				}
				return true;
			}
			// Нажата кнопка 'Reset'
			else if( e.target == m_btnReset )
			{
				//Сбрасываем все параметры в 0
				m_Filter.setBr(0);
				m_Filter.setContr(0);
				m_Filter.setSat(0);
				m_Filter.setRed(0);
				m_Filter.setGreen(0);
				m_Filter.setBlue(0);

				//Устанавливаем значения контролов
				setControlsData();	

				//Будем рисовать оригинальное изображение
				m_ImageDraw.m_img = m_imgOriginal;
				m_ImageDraw.repaint();
				return true;
			}

		}
		return super.action(e, o);
	}

	// getControlsData берет значения параметров фильтрования из контролов
	// и помещает их в фильтр изображения
	//------------------------------------------------------------------------
	private void getControlsData()
	{
		m_Filter.setBr(Integer.parseInt(m_editBr.getText()));
		m_Filter.setContr(Integer.parseInt(m_editContr.getText()));
		m_Filter.setSat(Integer.parseInt(m_editSat.getText()));
		m_Filter.setRed(Integer.parseInt(m_editRed.getText()));
		m_Filter.setGreen(Integer.parseInt(m_editGreen.getText()));
		m_Filter.setBlue(Integer.parseInt(m_editBlue.getText()));
	}

	// setControlsData берет значения параметров из фильтра и
	// и помещает их в текстовые поля
	//------------------------------------------------------------------------
	
	private void setControlsData()			
	{
		m_editBr.setText(String.valueOf(m_Filter.getBr()));
		m_editContr.setText(String.valueOf(m_Filter.getContr()));
		m_editSat.setText(String.valueOf(m_Filter.getSat()));
		m_editRed.setText(String.valueOf(m_Filter.getRed()));
		m_editGreen.setText(String.valueOf(m_Filter.getGreen()));
		m_editBlue.setText(String.valueOf(m_Filter.getBlue()));
	}	

	// doFilter очищает старое изображение и создает новое, применяя фильтр 
	// к оригинальной картинке
	//------------------------------------------------------------------------
	private void doFilter()
	{
		if( !m_fFiltering ) //запрещаем повторный вход в фильтр
		{
			//освобождаем память предыдущего изображения
			if( m_ImageDraw.m_img != null && m_ImageDraw.m_img != m_imgOriginal)
				m_ImageDraw.m_img.flush();
			
			m_fFiltering = true;
			m_ImageDraw.m_img = createImage(new FilteredImageSource(m_imgOriginal.getSource(),
										m_Filter));
		}
	}
}


//------------------------------------------------------------------------ 
// class ImageDraw - вспомогательный обьект для рисования изображения
//------------------------------------------------------------------------
class ImageDraw extends Canvas 
{
	public  Image			m_img = null; //картинка для рисования
	private ImageObserver	m_ImgObserver = null; //наблюдатель рисования
	boolean m_fIncrementalUpdate = false; //флаг пошаговой отрисовки

	// ImageDraw конструктор. Позволяет задать объект - наблюдатель рисования
	// Второй параметр конструктора отвечает за способ перерисовки - инкрементальная
	// или одношаговая
	//------------------------------------------------------------------------
	public ImageDraw(ImageObserver ImgObserver, boolean fIncrementalUpdate)
	{
		m_ImgObserver = ImgObserver;
		m_fIncrementalUpdate  = fIncrementalUpdate;
	}

	public ImageDraw()
	{
		this(null,false);
	}

	// imageUpdate вызывает наблюдатель рисования заданный в конструкторе
	// Если задана инкрементальная перерисовка - вызывает imageUpdate
	// базового класса
	//------------------------------------------------------------------------
	public boolean imageUpdate(Image  img, int  infoflags, int  x, int  y, int w, int  h)
	{
		boolean fRet = false;

		if( m_ImgObserver != null)
			fRet = m_ImgObserver.imageUpdate(img, infoflags, x, y, w,  h);

		if( m_fIncrementalUpdate )
			fRet = super.imageUpdate(img, infoflags, x, y, w, h);

		return fRet;
	}

	// update - рисуем изображение без перерисовки фона под изображением
	public void update(Graphics  g)
	{
		if( m_img != null )
		{
			int nX = 0;
			int nY = 0;

			int nW, nH;
			nW = m_img.getWidth(null);
			nH = m_img.getHeight(null);
			
			//если доступны размеры изображения 
			if( nW > 0 && nH > 0  )
			{
				Dimension dimS = size();
				//располагаем изображение в середине компонента
				nX = dimS.width/2  - nW / 2;
				nY = dimS.height/2 - nH / 2;

				//заполняем фон вокруг изображения
				if( nW < dimS.width  )
				{
			  		g.clearRect(0,        0,  nX, dimS.height);
					g.clearRect(nX + nW,  0,  dimS.width - (nX + nW), dimS.height);
				}
				if( nH < dimS.height )
				{
			  		g.clearRect(0,        0,  dimS.width, nY );
					g.clearRect(0,  nY + nH,  dimS.width, dimS.height - (nY + nH) );
				}
			}
			//рисуем cамо изображение
			g.drawImage( m_img, nX, nY, 
					    (m_ImgObserver == null || m_fIncrementalUpdate)? this : m_ImgObserver );
	
		}
		else
		{
		   // если изображения нет - просто рисуем фон
		   Rectangle rc = g.getClipRect();
		   g.clearRect(rc.x, rc.y, rc.width, rc.height);
		}
	}

	// paint - вызываем метод update 
	public void paint(Graphics  g)
	{
		update(g);
	}


}


//------------------------------------------------------------------------ 
// class ImgFilter - фильтр обработки изображения
//------------------------------------------------------------------------
class ImgFilter extends RGBImageFilter
{
	private int  m_nBr    = 0; //яркость -100, 100
	private int  m_nContr = 0; //контраст -100, 100
	private int  m_nSat   = 0; //насыщенность   -100, 100
	private int  m_nRed   = 0; //фактор красного  -100, 100
	private int  m_nGreen = 0; //фактор зеленого  -100, 100
	private int  m_nBlue  = 0; //фактор синего    -100, 100
	
	private double m_dAvgIntensity; //средняя интенсивность изображения
	private int    m_nContrTable[]; //таблица преобразования контрастности

	private int    m_nRedTable[];   //таблица преобразования красного цвета
	private int    m_nGreenTable[]; //таблица преобразования зеленого цвета
	private int    m_nBlueTable[];  //таблица преобразования синего цвета
	private float  m_fHSBvals[];    //буфер для оттенка, насыщенности, яркости 
	

	// ImgFilter конструктор - создает члены класса и инициирует
	// значения параметров по умолчанию
	//-----------------------------------------------
	public ImgFilter()
	{
		canFilterIndexColorModel = true;
		m_fHSBvals    = new float[3];
		m_nContrTable = new int[256];
		m_nRedTable   = new int[256];
		m_nGreenTable = new int[256];
		m_nBlueTable  = new int[256];
		m_dAvgIntensity = 127.5; //средняя интенсивность в середине диапазона 0-255
	}

	// Установка яркости. Параметр проверяется на 
	// граничные значения -100, 100
	//-----------------------------------------------
	public void setBr(int nBr)
	{
		m_nBr = validateParam(nBr);
	}

	// Установка контрастности. Параметр проверяется на 
	// граничные значения -100, 100
	// Вычисляется коэффициент изменения контрастности dGamma (от 0.01 до m_dAvgIntesity).
	// Затем формируется таблица преобразования контрастности для каждого
	// значения цвета ( 0 - 255)
	//-----------------------------------------------
	public void setContr(int nContr) 
	{
		m_nContr = validateParam(nContr); 

		if( m_nContr != 0 )
		{	
			double dGamma;
			
			if( m_nContr > 0 ) 
			{
			   // при увеличении контрастности dGamma > 1 и <= m_dAvgIntensity;
			   // расчитываем как tan(проценты увеличения контрастности) + 1		
			   dGamma = Math.tan( ( Math.PI/2 * (double)m_nContr) / 100 ) + 1;
			}
			else
			{
			   // при уменьшении контрастности dGamma < 1 и >= 0.01
			   // расчитываем пропорцинально m_nContr 
			   dGamma = ( (double)m_nContr ) / 100 + 1; 
			}

		      //проверка граничных значений коэффициента
			dGamma = Math.min(m_dAvgIntensity, dGamma);
			dGamma = Math.max(0.01, dGamma);

			int nVal;

			// формируется таблица преобразования контрастности для каждого
			// значения цвета ( 0 - 255) как отклонение от средней интенсивности
			// пропорциональное dGamma
			for( int i=0; i<256; i++ )
			{
				nVal = (int) ( m_dAvgIntensity + (i - m_dAvgIntensity) * dGamma );	
				
				if( nVal > 255 )
					nVal = 255;

				else if( nVal < 0 ) 
					nVal = 0;

				m_nContrTable[i] = nVal;
			}
		}
	}

	// Установка насыщенности. Параметр проверяется на 
	// граничные значения -100, 100
	//-----------------------------------------------
	public void setSat(int nSat)	 
	{
		m_nSat = validateParam(nSat);
	}
	
	// Установка фактора красного. Параметр проверяется на 
	// граничные значения -100, 100
	// Затем формируется таблица преобразования красного цвета для каждого
	// значения ( 0 - 255)
	//-----------------------------------------------
	public void setRed(int nRed)	
	{
		m_nRed = validateParam(nRed);
		fillBiasTable(m_nRedTable, m_nRed);
	}

	// Установка фактора синего. Параметр проверяется на 
	// граничные значения -100, 100
	// Затем формируется таблица преобразования синего цвета для каждого
	// значения ( 0 - 255)
	//-----------------------------------------------
	public void setGreen(int nGreen)
	{
		m_nGreen = validateParam(nGreen); 
		fillBiasTable(m_nGreenTable, m_nGreen);
	}

	// Установка фактора зеленого. Параметр проверяется на 
	// граничные значения -100, 100
	// Затем формируется таблица преобразования зеленого цвета для каждого
	// значения ( 0 - 255)
	//-----------------------------------------------
	public void setBlue(int nBlue)	
	{
		m_nBlue = validateParam(nBlue);
		fillBiasTable(m_nBlueTable, m_nBlue);
	}

	// fillBiasTable формирует таблицу преобразования цвета для каждого 
	// из возможных знечений (0 -255). Если nBias = -100 - уменьшаем цвет
	// на 100%, если  nBias = 100 - увеличиваем на 100%
	//-----------------------------------------------
	private void fillBiasTable(int nTable[], int nBias)
	{
		int nVal;
		for( int i=0; i<256; i++ )
		{
			nVal =  i + (i * nBias) / 100;	

			if( nVal > 255 )
					nVal = 255;

			else if( nVal < 0 ) 
					nVal = 0;

			nTable[i] = nVal;
		}

	}

	// Функции получения параметров фильтрования
	public int getSat()   { return m_nSat;   }
	public int getContr() { return m_nContr; }
	public int getBr()    { return m_nBr;    }
	public int getRed()   { return m_nRed;   }
	public int getGreen() { return m_nGreen; }
	public int getBlue()  { return m_nBlue;  }

	// filterRGB преобразует пикселы (или цвета палитры) 
	// исходного изображения в соотвествии с заданными параметрами
	//-----------------------------------------------
	public  int  filterRGB(int  x,  int  y,  int  rgb)  
	{
		if(  m_nSat !=  0 || m_nBr != 0 )
		{
			//преобразуем RGB модель цвета в модель HSB
			Color.RGBtoHSB( (rgb & 0x00ff0000) >> 16, //red
							(rgb & 0x0000ff00) >> 8,  //green 
							(rgb & 0x000000ff),		  //blue
							 m_fHSBvals );
			
			//пропорционально изменяем насыщенность и яркость
			m_fHSBvals[1] += ( m_fHSBvals[1] * m_nSat) / 100;
			m_fHSBvals[2] += ( m_fHSBvals[2] * m_nBr ) / 100;
			
			//проверяем граничные значения (0 - 1) насыщенности и яркости
			m_fHSBvals[1] = (float)Math.min(m_fHSBvals[1], 1 );
			m_fHSBvals[2] = (float)Math.min(m_fHSBvals[2], 1 );

			//обратное преобразование HSB к RGB
			rgb = Color.HSBtoRGB(m_fHSBvals[0], m_fHSBvals[1], m_fHSBvals[2]) | (rgb & 0xff000000);
		}

		// выделяем красный, синий и зеленый компоненты
		int  nRed   =  (rgb & 0x00ff0000) >>16;
		int  nGreen =  (rgb & 0x0000ff00) >> 8;
		int  nBlue  =   rgb & 0x000000ff;
	
		if( m_nContr != 0 )
		{
			//если задано изменение котрастности - изменяем
			//цвет по каждому каналу в соответствии с таблицей
			nRed   = m_nContrTable [ nRed   ];
			nGreen = m_nContrTable [ nGreen ];
			nBlue  = m_nContrTable [ nBlue  ];
		}

		//отклоняем цвета в соответсвии с таблицами изменения цветов
		nRed   = m_nRedTable   [ nRed   ];
		nGreen = m_nGreenTable [ nGreen ];
		nBlue  = m_nBlueTable  [ nBlue  ];

		//возвращаем упакованный результат в виде Int
		return (rgb & 0xff000000) | ( nRed  << 16 ) | (nGreen << 8) | nBlue;
    }

	// validateParam ограничивает значение входного параметра 
	// в пределах -100 - +100
	//-----------------------------------------------
	private int validateParam(int nParam)
	{
		if( nParam < -100 )
			nParam = -100;

		else if( nParam > 100 )
			nParam = 100;

		return nParam;
	}
}