我正在尝试将一些Delphi代码转换为Python PIL。这个问题是双管齐下的。首先,我不是德尔福程序员。其次,我今天之前没有使用PIL,所以我可能在这两个领域都有问题。
case PixelFormat of
pf32bit: PixSize:=4;
pf24bit: PixSize:=3;
pf16bit: PixSize:=2;
end;
BitCounter:=0;
for i:=0 to Height-1 do begin
Row:=ScanLine[i];
PB:=@Row[PixSize-1];
for j:=0 to Width-1 do begin
Ch[BitCounter] := (PB^ and 1);
....
inc(BitCounter);
inc(PB, PixSize);
end;
所以我得到PixelFormat属性表示每个像素的大小(以字节为单位)。我还得到ScanLine方法应该得到一个代表该行的像素数组。我没有得到的是我倾向于将每个像素可视化为RGB值。我习惯于提取颜色值的最低位。但是,我不认为我甚至不确定现有代码正在提取什么。我有一些python PIL代码将提取同一图像中每个像素的RGB值,但我不知道RGB值的元组如何与早期代码中获得的PB变量进行比较。根据一些实验,我猜它根本没有比较。
提前致谢。
答案 0 :(得分:1)
如果有人试图以后再这样做。感谢David帮助澄清了ScanLine的回归。
from PIL import Image
img = Image.open('picture.gif')
(width, height) = img.size
conv = img.convert("RGB").getdata()
bt = []
for h in range(height):
for w in range(width):
pixel = conv.getpixel((w, h))[0] # getpixel returns a tuple (R,G,B)
bt.append((pixel & 0x1))
答案 1 :(得分:-1)
这将有助于显示您正在使用的变量是如何定义的,以便我们可以看到您尝试使用它们的内容。也就是说,ScanLine属性是一个表示代表像素的字节的数组。也就是说,你需要一个像case语句一样的函数来确定字节数。但是你需要将每个ScanLine作为指向字节数组的指针拉出来。
因此,ScanLine数组中的条目数是Bitmap1.Height,这意味着您拥有该部分。但其余的则有所不同。假设我们将名为row的变量定义为指针。然后要在数组中找到特定的像素,您必须相应地设置另一个指针。
不确定这是否得到它,因为它经过了非常轻微的测试。我只是使用Longint来表示我正在拉回的像素数据。您可以使用更适合您需要的东西来提取RGB数据,但希望这能说明如何处理ScanLine属性以获取您需要的像素数据:
var
i, j: integer;
row: pointer;
pixel: pointer;
pixelsize: integer;
thepixel: longint;
begin
for i := 0 to (Image1.Picture.Height - 1) do
begin
row := Image1.Picture.Bitmap.ScanLine[i];
pixelsize := GetPixelSize(Image1.Picture.Bitmap.PixelFormat);
pixel := row;
for j := 0 to (Image1.Picture.Width - 1) do
begin
thepixel := Longint(Pixel^);
// Memo1.Lines.Add(IntToHex(thepixel, 12));
Inc(Longint(Pixel), pixelsize);
end;
end;
end;