У меня проблема с растровым изображением в C++/CLI. Короче говоря, мне нужно загрузить фрагмент Bitmap в PictureBox, отобразить его и переместить его на несколько строк ниже. Я делаю следующие шаги:Перемещение растрового изображения внутри PictureBox
1 - Загрузите полное растровое изображение с жесткого диска и получите его параметры (ширина, высота и т. Д.).
2 - Создайте PictureBox, который сможет полностью содержать этот растровый рисунок.
3 - Создайте растровое изображение, которое я использую в качестве области рисования, и поставлю его внутри PictureBox.
4 - Скопируйте фрагмент (первые 150 строк) исходного растрового изображения в мою область рисования и отобразите его.
5 - Переместите этот кусок на несколько строк ниже. (Вот моя проблема).
Когда я перемещаю изображение, у меня есть ошибка: изображение отображается влево, а справа - левая часть изображения. Я загрузил фотографии:
Это кусок изображения, прежде чем переместить его, все в порядке. http://i58.tinypic.com/2duf48x.png
Это изображение после перемещения, как вы видите, оно отображается влево. http://i61.tinypic.com/jz9ond.png
метод я использую, чтобы "двигаться" изображения:
1 - LockBits и получить anIntPtr, который я конвертировать в неподписанные символ *. 2 - Используйте memcpy (или memmove) для перемещения фрагмента.
Вот код, они являются конструктор класса (форма Windows, конструктор) и метод я использую, чтобы отобразить кусок и переместить его:
MyForm(){
InitializeComponent();
//Get a test srcIm and it's parameters.
srcIm = gcnew Bitmap("./img/zhbackground.bmp");
iWidth = srcIm->Width;
iHeigth = srcIm->Height;
pxF = srcIm->PixelFormat;
Bpp = Image::GetPixelFormatSize(pxF)/8;
//Prepare a PictureBox, which will be given as parameter to Windows Form.
pb = gcnew PictureBox();
pb->SizeMode = PictureBoxSizeMode::StretchImage;
pb->Size = Drawing::Size(iWidth, iHeigth);
pb->Location = Drawing::Point(0, 0);
//Create draw area and put it into the PictureBox.
drawArea = gcnew Bitmap(pb->Width, pb->Height, pxF);
pb->Image = drawArea;
this->Controls->Add(this->pb);
}
void test(){
//This is the number of lines of my image chunk.
int nLines = 150;
//First, load the first 150 lines of my image (that's on hard drive).
BitmapData ^srcData = srcIm->LockBits(
Drawing::Rectangle(0, 0, iWidth, iHeigth),
ImageLockMode::ReadOnly,
pxF
);
unsigned char *srcStream = (unsigned char*)srcData->Scan0.ToPointer();
//Prepare the draw area for paint my image chunk.
BitmapData ^dstData = drawArea->LockBits(
Drawing::Rectangle(0, 0, iWidth, iHeigth),
ImageLockMode::ReadWrite,
pxF
);
unsigned char *dAhandler = (unsigned char*)dstData->Scan0.ToPointer();
//Paint the chunk. (My image's 150 first lines)
memcpy(dAhandler, srcStream, iWidth * Bpp * nLines);
//Unlock and refresh to see the image.
drawArea->UnlockBits(dstData);
this->pb->Refresh();
//Wait 1 second...
Threading::Thread::Sleep(1000);
//Unlock draw area to move the image.
dstData = drawArea->LockBits(
Drawing::Rectangle(0, 0, iWidth, iHeigth),
ImageLockMode::ReadWrite,
pxF
);
dAhandler = (unsigned char*)dstData->Scan0.ToPointer();
//First, move the image from the beggining to 150 lines below.
memcpy(&dAhandler[nLines * iWidth * Bpp], dAhandler, iWidth * nLines * Bpp);
//Paint the "hole" with black.
memset(dAhandler, 0, iWidth * Bpp * nLines);
//Unlock and display the image.
drawArea->UnlockBits(dstData);
this->pb->Refresh();
//Unlock the source image (image load from hard drive).
srcIm->UnlockBits(srcData);
}
Я испытал много способов:
1 - Я прочитал, что если вы используете LockBits(), IntPtr, который вы можете получить, представляет собой массив байтов пикселей, за которым следует другой. Это означает, что у меня не может быть проблем с такими проблемами, как организация Bitmap в памяти и т. Д.
2 - Я протестировал memcpy и memmove.
3 - Я проверил, чтобы сделать простой цикл.
Ничего не работает, я не знаю, что делать.
Спасибо, привет.