Страница: 1 | 2 | 3 |
Вопрос: C# : Очень медленно работает код!
Добавлено: 04.09.10 11:05
Автор вопроса: Лёха | Web-сайт: supersait16.ucoz.ru
В этом коде производится приращение значений r,g,b - по выбору(из ComboBox)
public partial class LavelsRGB : Form
{
Bitmap IMG = null;
BitmapData BmpData = null;
IntPtr PixPointer = IntPtr.Zero;
byte[] MSV = null;
const int Level_R = 0;
const int Level_G = 1;
const int Level_B = 2;
int Step = 0;
int _Width = 0;
int _Height = 0;
public LavelsRGB(Bitmap MainBitmap)
{
InitializeComponent();
if (MainBitmap == null)
throw new ArgumentException();
else
{
IMG = MainBitmap;
PreviewBox.Image = (Image)IMG;
}
switch (IMG.PixelFormat)
{
case PixelFormat.Alpha | PixelFormat.Format32bppArgb | PixelFormat.Format32bppPArgb:
{
Step = 4;
break;
}
case PixelFormat.Format24bppRgb:
{
Step = 3;
break;
}
default:
{
throw new ArgumentException("Неподходящий формат пикселей!");
break;
}
}
_Width = IMG.Width;
_Height = IMG.Height;
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
textBox1.Text = trackBar1.Value.ToString();
int Color_Buffer = 0;
if (IMG != null)
{
BmpData = IMG.LockBits(new Rectangle(0, 0, IMG.Width, IMG.Height),
ImageLockMode.ReadWrite, IMG.PixelFormat);
PixPointer = BmpData.Scan0;
MSV = new byte[_Height * _Width * Step ];
Marshal.Copy(PixPointer, MSV, 0, MSV.Length);
switch (comboBox1.SelectedIndex)
{
case Level_R:
{
for (int AX = 0; AX < BmpData.Width; AX++)
{
for (int AY = 0; AY < BmpData.Height; AY++)
{
Color_Buffer = MSV[((AY * _Width + AX) * Step ) + 2];
if ((Color_Buffer != 255) && (Color_Buffer > 0))
{
if (Color_Buffer + trackBar1.Value > 255)
MSV[((AY * _Width + AX) * Step ) + 2] = 255;
else if (Color_Buffer + trackBar1.Value < 0)
MSV[((AY * _Width + AX) * Step ) + 2] = 1;
else
MSV[((AY * _Width + AX) * Step ) + 2] += Convert.ToByte(trackBar1.Value);
}
}
}
break;
}
case Level_G:
{
for (int AX = 0; AX < BmpData.Width; AX++)
{
for (int AY = 0; AY < BmpData.Height; AY++)
{
Color_Buffer = MSV[((AY * _Width + AX) * Step ) + 1];
if ((Color_Buffer != 255) && (Color_Buffer > 0))
{
if (Color_Buffer + trackBar1.Value > 255)
MSV[((AY * _Width + AX) * Step ) + 1] = 255;
else if (Color_Buffer + trackBar1.Value < 0)
MSV[((AY * _Width + AX) * Step ) + 1] = 1;
else
MSV[((AY * _Width + AX) * Step ) + 1] += Convert.ToByte(trackBar1.Value);
}
}
}
break;
}
case Level_B:
{
for (int AX = 0; AX < BmpData.Width; AX++)
{
for (int AY = 0; AY < BmpData.Height; AY++)
{
Color_Buffer = MSV[((AY * _Width + AX) * Step ) + 0];
if ((Color_Buffer != 255) && (Color_Buffer > 0))
{
if (Color_Buffer + trackBar1.Value > 255)
MSV[((AY * _Width + AX) * Step ) + 0] = 255;
else if (Color_Buffer + trackBar1.Value < 0)
MSV[((AY * _Width + AX) * Step ) + 0] = 1;
else
MSV[((AY * _Width + AX) * Step ) + 0] += Convert.ToByte(trackBar1.Value);
}
}
}
break;
}
}
Marshal.Copy(MSV, 0, PixPointer, MSV.Length);
IMG.UnlockBits(BmpData);
PreviewBox.Image = (Image)IMG;
}
}
}
Он обробатывает изображение 1024x768 24bpp за 20сек(наверно даже медленнее чем Get/Set Pixel).
В статьях написано что через Lock/Unlock Bits работает быстро, а на деле - 20сек.Это так и должно быть или я коряво написал?
Ответить
Номер ответа: 7Автор ответа: EROS
Вопросов: 58Ответов: 4255
Профиль | | #7
Добавлено: 04.09.10 18:10
В общем случае это должно выглядеть примерно так:
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace VbNet.Ru
{
public class ImageHelper
{
public event EventHandler ImageChanged;
private static PixelFormat allowed = PixelFormat.Format24bppRgb | PixelFormat.Format32bppRgb | PixelFormat.Format32bppArgb;
int bytesInPixel;
byte [] originBytes;
public ImageHelper(Bitmap origin)
{
if (origin == null ) throw new ArgumentNullException();
if ((allowed & origin.PixelFormat) != origin.PixelFormat) throw new NotSupportedException();
Image = new Bitmap(origin);
Initialize();
}
private void Initialize()
{
bytesInPixel = (Image.PixelFormat == PixelFormat.Format32bppArgb) ? 4 : 3;
originBytes = new byte [Image.Width * Image.Height * bytesInPixel];
BitmapData bitmapData = Image.LockBits(new Rectangle(0, 0, Image.Width, Image.Height), ImageLockMode.ReadOnly , Image.PixelFormat);
Marshal.Copy(bitmapData.Scan0, originBytes, 0, originBytes.Length);
Image.UnlockBits(bitmapData);
}
public void SetLevel(Levels level, int offset)
{
if (offset < -255 || offset > 255) throw new ArgumentOutOfRangeException();
byte [] imageBytes = new byte [originBytes.Length];
BitmapData bitmapData = Image.LockBits(new Rectangle(0, 0, Image.Width, Image.Height), ImageLockMode.ReadWrite, Image.PixelFormat);
IntPtr pointer = bitmapData.Scan0;
Marshal.Copy(pointer, imageBytes, 0, imageBytes.Length);
for (int i = (int )level; i < imageBytes.Length; i += bytesInPixel)
{
int value = originBytes+offset;
if (value > 255) value = 255;
if (value < 0) value = 0;
imageBytes = (byte )value;
}
Marshal.Copy(imageBytes, 0, pointer, imageBytes.Length);
Image.UnlockBits(bitmapData);
OnImageChanged();
}
#region properties...
public Bitmap Image { get ; private set ; }
#endregion
#region OnImageChanged
public virtual void OnImageChanged()
{
if (ImageChanged != null )
ImageChanged(this , EventArgs.Empty);
}
#endregion
}
}
Пример использования (тестовый проект C# FW 3.5) выложил тут:
http://clip2net.com/s/w2v5
Ответить
Номер ответа: 11Автор ответа: Лёха
Вопросов: 20Ответов: 79
Web-сайт: supersait16.ucoz.ru Профиль | | #11
Добавлено: 06.09.10 18:46
Сделал так как ты сказал,но вот что он делает(в исходнике всё работает нормльно,а у меня...) - http://www.supersait16.ucoz.ru/FTP/snimok.jpg
public partial class LavelRGB : Form
{
public enum CorrectionLevel
{
Blue = 0, Green = 1, Red = 2
}
public Bitmap IMG;
private int BytesInPixel;
private byte [] OriginBytes;
public LavelRGB(Bitmap MainBitmap)
{
InitializeComponent();
if (MainBitmap == null )
{
throw new ArgumentNullException();
}
if (MainBitmap.PixelFormat == PixelFormat.Format32bppArgb)
{
BytesInPixel = 4;
}
else if (MainBitmap.PixelFormat == PixelFormat.Format24bppRgb)
{
BytesInPixel = 3;
}
else
{
throw new NotSupportedException("Неподходяший формат пикселей!" );
}
IMG = new Bitmap(MainBitmap);
PreviewBox.Image = (Image)IMG;
Initialize();
}
private void Initialize()
{
OriginBytes = new byte [IMG.Height * IMG.Width * BytesInPixel];
BitmapData BmpData = IMG.LockBits(new Rectangle(0, 0, IMG.Width, IMG.Height),
ImageLockMode.ReadOnly , IMG.PixelFormat);
Marshal.Copy(BmpData.Scan0, OriginBytes, 0, OriginBytes.Length);
IMG.UnlockBits(BmpData);
}
private void CorrectLevel(CorrectionLevel Level, int Offset)
{
if ((Offset < -255) || (Offset > 255))
throw new ArgumentException();
byte [] ImageBytes = new byte [OriginBytes.Length];
BitmapData BData = IMG.LockBits(new Rectangle(0, 0, IMG.Width, IMG.Height),
ImageLockMode.ReadWrite, IMG.PixelFormat);
IntPtr Pointer = BData.Scan0;
Marshal.Copy(Pointer, ImageBytes, 0, ImageBytes.Length);
for (int I = Convert.ToInt32(Level); I < ImageBytes.Length; I += BytesInPixel)
{
int Value = OriginBytes + Offset;
if (Value > 255) Value = 255;
if (Value < 0) Value = 0;
ImageBytes = Convert.ToByte(Value);
}
Marshal.Copy(ImageBytes, 0, Pointer, ImageBytes.Length);
IMG.UnlockBits(BData);
PreviewBox.Image = (Image)IMG;
}
public Bitmap MainImage
{
get { return IMG; }
}
private void Track_Red_Scroll(object sender, EventArgs e)
{
ValueRed.Text = Track_Red.Value.ToString();
CorrectLevel(CorrectionLevel.Red, Track_Red.Value);
}
private void ValueRed_TextChanged(object sender, EventArgs e)
{
Track_Red.Value = Convert.ToInt32(ValueRed.Text);
}
private void Track_Green_Scroll(object sender, EventArgs e)
{
ValueGreen.Text = Track_Green.Value.ToString();
CorrectLevel(CorrectionLevel.Green, Track_Green.Value);
}
private void ValueGreen_TextChanged(object sender, EventArgs e)
{
Track_Green.Value = Convert.ToInt32(ValueGreen.Text);
}
private void Track_Blue_Scroll(object sender, EventArgs e)
{
ValueBlue.Text = Track_Blue.Value.ToString();
CorrectLevel(CorrectionLevel.Blue, Track_Blue.Value);
}
private void ValueBlue_TextChanged(object sender, EventArgs e)
{
Track_Blue.Value = Convert.ToInt32(ValueBlue.Text);
}
}
Ответить
Страница: 1 | 2 | 3 |
Поиск по форуму