0

在我找到并修改的位图阅读器中,一些图像的前几种颜色大量不准确,在其他图像中它读取完美,在刚才,我必须读取的图像的前7种左右颜色是一点也不准确。我不明白字节顺序,所以请帮忙!

这是我修改后的代码副本:

---
-- (Evil Steve)Because I'm a kind and wonderful person: http://www.gamedev.net/topic/572784-lua-read-bitmap/
---

function error(err)
    -- Replace with your own error output method:
    print(err);
end

-- Helper function: Parse a 16-bit WORD from the binary string
function ReadWORD(str, offset)
    local loByte = str:byte(offset);
    local hiByte = str:byte(offset+1);
    return hiByte*256 + loByte;
end

-- Helper function: Parse a 32-bit DWORD from the binary string
function ReadDWORD(str, offset)
    local loWord = ReadWORD(str, offset);
    local hiWord = ReadWORD(str, offset+2);
    return hiWord*65536 + loWord;
end

-- Process a bitmap file in a string, and call DrawPoint for each pixel
function OpenBitmap(File, Stream)
    if Stream == nil then Stream = false end
    local bytecode = File:read("*a")

    -------------------------
    -- Parse BITMAPFILEHEADER
    -------------------------
    local offset = 1;
    local bfType = ReadWORD(bytecode, offset);
    if(bfType ~= 0x4D42) then
        error("Not a bitmap file (Invalid BMP magic value)");
        return;
    end
    local bfOffBits = ReadWORD(bytecode, offset+10);

    -------------------------
    -- Parse BITMAPINFOHEADER
    -------------------------
    offset = 15; -- BITMAPFILEHEADER is 14 bytes long
    local biWidth = ReadDWORD(bytecode, offset+4);
    local biHeight = ReadDWORD(bytecode, offset+8);
    local biBitCount = ReadWORD(bytecode, offset+14);
    local biCompression = ReadDWORD(bytecode, offset+16);

    if(biBitCount ~= 24) then
        error("Only 24-bit bitmaps supported (Is " .. biBitCount .. "bpp)");
        return;
    end

    if(biCompression ~= 0) then
        error("Only uncompressed bitmaps supported (Compression type is " .. biCompression .. ")");
        return;
    end

    ---------------------
    -- Parse bitmap image
    ---------------------
    local TmpImg = {}
    if Stream == false then
        for y = biHeight-1, 0, -1 do
            offset = bfOffBits + (biWidth*biBitCount/8)*y + 1;
            for x = 0, biWidth-1 do
                local b = bytecode:byte(offset);
                local g = bytecode:byte(offset+1);
                local r = bytecode:byte(offset+2);
                offset = offset + 3;

                TmpImg[#TmpImg+1] = {r,g,b}
            end
        end
    else
        for y = biHeight-1, 0, -1 do
            offset = bfOffBits + (biWidth*biBitCount/8)*y + 1;
            for x = 0, biWidth-1 do
                local b = bytecode:byte(offset);
                local g = bytecode:byte(offset+1);
                local r = bytecode:byte(offset+2);
                offset = offset + 3;

                TmpImg[#TmpImg+1] = r
                TmpImg[#TmpImg+1] = g
                TmpImg[#TmpImg+1] = b
            end
        end
    end

    return TmpImg, biWidth, biHeight
end

function OpenBmp(FileName, Stream)
    if Stream == nil then Stream = false end
    if FileName == nil then
        return false
    end

    local File = assert(io.open(FileName, 'rb'))
    local Data, Width, Height = OpenBitmap(File, Stream)

    File:close()
    return Data, Width, Height
end

遗憾的是,我不能给你我用它运行的代码,因为它有太多的依赖关系需要打扰,但它的输出是:

<254, 254, 254, 256>
<99, 254, 254, 256>
<49, 74, 91, 256>

使用以下 bmp 颜色运行时:

<90, 106, 113, 256>
<188, 194, 197, 256>
<254, 254, 254, 256>

我没有看到任何模式,并且 bmp 阅读器似乎很有意义,阅读时它不会打印任何错误,并且我确保根据需要将 bmp 保存为 24 位。所有帮助表示赞赏:-)

4

1 回答 1

0

在上面的示例中,偏移量没有考虑到行宽必须始终是 4 字节宽的倍数,如果它低于 4 的倍数则填充它。您可以通过将行宽四舍五入到最接近的 4 倍数来解决此问题,这解释了为什么该函数有时能准确读取图像,而有时则不能。

开始时像素的行为是错误的,但后来准确的其余部分是由于爬行,从逻辑上讲,第一个是准确的,最后一个是不准确的,但是由于位图被读取底部,爬行的方式相反 -上下左右。

于 2013-08-02T02:36:12.487 回答