我有1个位图对象:1024px和高度:768 px
我想将此位图对象剪切为左右两部分,但我不想在画布中使用DrawBitmap方法,因为此方法可以使用更多的CPU然后使用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);
如果我这样做,他可以复制但不会留下位图的一部分:(他从上到下复制了一半。
这幅画正是我想做的。
在剪切过程之后,我需要这样做而不使用任何循环(如while或for)
由于
答案 0 :(得分:4)
没有办法!正如您所发现的那样,图像数据是逐行存储在存储器中的(因此扫描线)。你想要的只有在逐列的情况下才有可能。没有任何循环,这是不可能的。
答案 1 :(得分:2)
正如您所注意到的,扫描线是从左到右的一行像素。图像中每个垂直高度像素都有一条扫描线。
您的1024px x 768px图像有768条扫描线。从扫描线复制前半部分数据会产生图像的上半部分。
您不必浏览每个像素,您可以跳过,因为所有内容都已编入索引。
但是,既然你想要两半,那么你就不会因为经历整个事情而浪费任何工作。在迭代数据时,同时复制左右两部分。因此,对于第一条扫描线,将前半部分像素复制到左侧图像,将其余像素复制到右侧图像,转到下一行,然后重复。
这应该比DrawBitmap少两倍。
此外,不是加载图像,显示它,然后将其拆分,而是在加载图像时将其拆分。
你仍然需要一个循环,除非你想写所有东西768次。
从技术上讲,你可以旋转图像并按照你想要的方式进行操作,但旋转它也需要循环,你必须在完成后将其旋转回来。
答案 2 :(得分:2)
使用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)
);