Как я могу скопировать память TBitmap с помощью функции Windows CopyMemory - PullRequest
1 голос
/ 03 декабря 2011

У меня есть 1 растровый объект с разрешением 1024 пикселей и высотой 768 пикселей

Я хочу разрезать этот растровый объект на 2 части, как слева и справа, но я не хочу использовать метод DrawBitmap на холсте, потому что этот метод может использовать больше ЦП, чем CopyMemory.

Я не хочу использовать этот метод (leftImg.Canvas.DrawBitmap (MainBmp, RectF (0,0, MainBmp.Width div 2, bmp.Height), RectF (0,0, leftImg.Width, leftImg.Height), 1, True); )

MainBmp := TBitmap.Create(1024, 768);

leftImg := TBitmap.Create(MainBmp.Width div 2, MainBmp.Height);
rightImg := TBitmap.Create(MainBmp.Width div 2, MainBmp.Height);

leftBits := PAlphaColorArray(leftImg.Scanline[0]);

CopyMemory(@leftBits[0], @MainBmp.StartLine[0], (MainBmp.Width div 2) * bmp.Height);

если я так делаю, он может копировать, но не левую часть растрового изображения :( он копирует половину сверху вниз.

Этот рисунок - именно то, что я хочу сделать.

enter image description here

После процессов вырезания мне нужно вот так без использования какой-либо петли (например, while или for)

enter image description here

Спасибо

Ответы [ 3 ]

4 голосов
/ 03 декабря 2011

Не могу сделать!Как вы узнали, данные изображения располагаются в памяти построчно (отсюда scanline ).То, что вы хотите, может быть возможно только в том случае, если это столбец за столбцом.Без петель это невозможно.

2 голосов
/ 03 декабря 2011

Используйте метод TCanvas.CopyRect() для копирования частей одного TCanvas в другой TCanvas. Это позволяет двум растровым изображениям иметь разные форматы пикселей. ОС будет обрабатывать различия внутри вас:

MainBmp := TBitmap.Create(1024, 768); 

leftImg := TBitmap.Create(MainBmp.Width div 2, MainBmp.Height); 
rightImg := TBitmap.Create(MainBmp.Width div 2, MainBmp.Height); 

leftImg.Canvas.CopyRect(
  Rect(0, 0, leftImg.Width, leftImg.Height),
  MainBmp.Canvas,
  Rect(0, 0, leftImg.Width, leftImg.Height)
);

rightImg.Canvas.CopyRect(
  Rect(0, 0, rightImg.Width, rightImg.Height),
  MainBmp.Canvas,
  Rect(leftBmp.Width, 0, rightImg.Width, rightImg.Height)
);
2 голосов
/ 03 декабря 2011

Как вы заметили, отсканированная строка представляет собой ряд пикселей слева направо.Для каждого пикселя вертикальной высоты изображения имеется одна линия развертки.

Ваши изображения размером 1024px x 768px имеют 768 строк развертки.Копирование первой половины данных из линий сканирования дает вам верхнюю половину изображения.

Вам не нужно проходить каждый пиксель, вы можете пропустить его, поскольку все проиндексировано.

Однако, поскольку вы хотите обе половины, вы не теряете работу, выполняя все это.Выполняя итерацию по данным, копируйте одновременно левую и правую части.Таким образом, для первой строки сканирования скопируйте первую половину пикселей на левое изображение, а остальные пиксели - на правое изображение, перейдите к следующей строке и повторите.

Это должно быть меньше работы, чем DrawBitmapдважды.

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

Вам все равно понадобится цикл, если вы не хотитеписать все 768 раз.

Технически, вы можете вращать изображение и делать его так, как вы хотите, но вращение тоже потребует циклов, и вам придется повернуть его обратно, когда вы закончите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...