Bitmap ^ bmp = gcnew Bitmap(780,580,System::Drawing::Imaging::PixelFormat::Format8bppIndexed);
Rectangle rect = Rectangle(0,0,bmp->Width,bmp->Height);
System::Drawing::Imaging::BitmapData^ bmpData = bmp->LockBits( rect, System::Drawing::Imaging::ImageLockMode::ReadWrite, bmp->PixelFormat );
IntPtr ptr = bmpData->Scan0;
int bytes = bmpData->Stride * bmp->Height;
array<Byte>^rgbValues = gcnew array<Byte>(bytes);
System::Runtime::InteropServices::Marshal::Copy( ptr, rgbValues, 0, bytes );
for ( int counter = 0; counter < rgbValues->Length; counter++ )
rgbValues[ counter ] = Convert::ToInt32(*(CadrBuff+counter));
System::Runtime::InteropServices::Marshal::Copy( rgbValues, 0, ptr, bytes );
bmp->UnlockBits( bmpData );
pictureBox1->Image = bmp;
быстрый вывод картинки в windows Form
Делаю вот так:
[HTML]
Bitmap ^ image1 = gcnew Bitmap(xs, ys);
for(i=0;i<INPUT_CADRS;i++)
{
CadrBuff = new UINT8 [xs*ys];
rc=VsCamCmd(Cam,VSCAMERA_PORT_CAM_NEXT_CADR,CadrBuff, xs*ys);
k=0;
for ( b = 0; b < image1->Height; b++ )
{
for ( a = 0; a < image1->Width; a++ )
{
c =Convert::ToInt32(*(CadrBuff+k));
Color newColor = Color::FromArgb( c, c, c );
image1->SetPixel( a, b, newColor );
k++;
}
}
pictureBox1->Image = image1;
this->Refresh();
[/HTML]
картинку выводит нормально, но очень долго. Как сделать быстрее???
cadrbuff это буфер содержащий точки изображения. Картинка 8 битная, значения точки это значение градация серого
Цитата: S1avik
Как сделать быстрее???
Забыть про SetPixel и начать пользоваться Bitmap.LockBits() + BitmapData.Scan0 для прямого доступа к памяти, в которой хранится изображение.
И еще вот какой вопрос, я когда картинку вывожу, ничего с формой делать не могу, а хотелось бы чтоб параметры какие то задавались, вкладки всякие работали. Как это сделать???
Цитата: hardcase
А по ссылкам пробовали ходить?????????
А что такое ссылки??????? :D :D
Цитата:
И еще вот какой вопрос, я когда картинку вывожу, ничего с формой делать не могу, а хотелось бы чтоб параметры какие то задавались, вкладки всякие работали. Как это сделать???
У тебя просто вывод через SetPixel настолько медленный, что блокирует перерисовку окна. Будешь выводить правильным способом - всё будет щелкать и работать.
[HTML]
Bitmap ^ bmp = gcnew Bitmap("c:\\image1.bmp");
Rectangle rect = Rectangle(0,0,bmp->Width,bmp->Height);
System::Drawing::Imaging::BitmapData^ bmpData = bmp->LockBits( rect, System::Drawing::Imaging::ImageLockMode::ReadWrite, bmp->PixelFormat );
IntPtr ptr = bmpData->Scan0;
int bytes = bmpData->Stride * bmp->Height;
array<Byte>^rgbValues = gcnew array<Byte>(bytes);
System::Runtime::InteropServices::Marshal::Copy( ptr, rgbValues, 0, bytes );
for ( int counter = 0; counter < rgbValues->Length; counter++ )
rgbValues[ counter ] = Convert::ToInt32(*(CadrBuff+counter));
System::Runtime::InteropServices::Marshal::Copy( rgbValues, 0, ptr, bytes );
bmp->UnlockBits( bmpData );
pictureBox1->Image = bmp;
[/HTML]
использую бмпшку такого же размера как и моя картинка которую буду выводить, потом перерисовываю её. Подскажите как сделать это правильней, что бы не брать картинку и потом её перерисовывать, а сразу вывести нужное мне изображение из буфера???
Цитата: S1avik
Подскажите как сделать это правильней, что бы не брать картинку и потом её перерисовывать, а сразу вывести нужное мне изображение из буфера???
Bitmap Constructor (Int32, Int32, PixelFormat)
И кстати в C++ можно обойтись без промежуточного массива - нужно напрямую работать с указателем Scan0.
а пример где нибудь есть как работать со Scan0 на прямую?
Цитата: S1avik
а пример где нибудь есть как работать со Scan0 на прямую?
Scan0 это указатель в формате System.IntPtr на память, в которой находится изображение. Что такое указатель отлично расписано в тысячах книг. Преобразовать в указатель C++ можно с помощью метода ToPointer().
void* ToPointer()
ToPointer()- это указатель на функцию????
а у меня буфер, как тогда применить? вот так: void* CadrBuff; ?
тогда не понятно как правильно использовать scan().
если это все так просто и делается с помощью пару строчек то почему никто не напишет как??? к сожалению я даже представить пока не могу как это сделать (
Написали же, что это метод возвращающий указатель.
Код:
но выводит не то что надо. на мсдн было написанно что код применим для 24 битного изображения, а у меня 8, что нужно еще исправить?
И ещё. Советую использовать using'и:
Код:
using namespace System::Drawing::Imaging;
using namespace System::Runtime::InteropServices;
using namespace System::Runtime::InteropServices;
Тогда можно будет писать коротко: BitmapData, Marshal::Copy, без указания пространств имён. Код станет прозрачнее, яснее.
поменял convert::ToInt32 на Convert::ToByte но не помогло, выводит разные цвета. А должна быть черно белая картинка.