这可能是一件非常简单的事情,但我不太明白如何把这些部分放在一起。
This question
和
this question
以及
this page
在API文档中,所有这些都暗示了答案,但是我还没有从它们那里得到我需要的东西。
所以现在我正在尝试实现一个nave小程序来打开一个图像,把像素放到一个数组中,对它们进行一点处理,然后将更新后的像素保存回一个新的图像。在这个特殊的例子中,我想把每个像素周围3x3窗口的平均值作为一个简单的模糊。具体的操作并不太重要(肯定有更有效的方法,我现在特别想写一个nave版本,以便以后与其他版本进行比较),但我还没能想出如何做到这一点。现在我得到的是:
let accessClampedArrayWithDefault (arr: uint32[][]) width height def x y : uint32[] =
if x < 0 || x > width-1 || y < 0 || y > height-1 then
def
else
arr.[x + width * y]
let extractPixelParts (p: Rgba32) =
let R = uint32 p.R
let G = uint32 p.G
let B = uint32 p.B
let A = uint32 p.A
[|R; G; B; A|]
[<EntryPoint>]
let main argv =
use img = Image.Load(@"D:\Users\sampleimage.jpg")
let mutable out_img = img.Clone()
let pxs = img.GetPixelSpan().ToArray() |> Array.map extractPixelParts
let mutable (nps: uint32[][]) = Array.zeroCreate pxs.Length
let ac = accessClampedArrayWithDefault pxs img.Width img.Height [|0u;0u;0u;0u|]
for x in 0..img.Width-1 do
for y in 0..img.Height-1 do
let p = ac x y
for z in -1..1 do
for w in -1..1 do
let q = ac (x + z) (y + w)
nps.[x + y * img.Width] <- Array.zip p q |> Array.map (fun (a,b) -> a + b)
nps.[x + y * img.Width] <- Array.map (fun i -> float i / 9.0 |> uint32 ) nps.[x + y * img.Width]
let rpx = Array.collect (fun a -> Array.map byte a) nps
let out_img = Image.Load<Rgba32>(img.GetConfiguration(), rpx, Formats.Jpeg.JpegDecoder())
printfn "out_img's width is %d and height is %d" out_img.Width out_img.Height
但它正在失败,只有一个例外
let out_img =
所以,我的问题是,我怎样才能取出像素,并以大于8位(例如32位)的可变大小处理它们/每个通道,以便在将最终结果转换回字节,然后将其重新构造成可以保存到磁盘的内容之前,执行不能用每个通道8位表示的中间操作作为一个形象?
我很可能忘了提一些重要的事情,所以请随时要求澄清:)谢谢。