在Clojure中创建给定r g b的像素

在Clojure中创建给定r g b的像素,clojure,Clojure,使用我可以从图像中获得一个像素,如[rgb]。使用这个,我已经验证了这个提取部分几乎肯定是工作的。这是执行提取的imagez代码: (defn components-rgb "Return the RGB components of a colour value, in a 3-element vector of long values" ([^long rgb] [(bit-shift-right (bit-and rgb 0x00FF0000) 16) (bit-shi

使用我可以从图像中获得一个像素,如
[rgb]
。使用这个,我已经验证了这个提取部分几乎肯定是工作的。这是执行提取的imagez代码:

(defn components-rgb
  "Return the RGB components of a colour value, in a 3-element vector of long values"
  ([^long rgb]
   [(bit-shift-right (bit-and rgb 0x00FF0000) 16)
    (bit-shift-right (bit-and rgb 0x0000FF00) 8)
    (bit-and rgb 0x000000FF)]))
我需要做与提取相反的事情。以下是正在提取的“颜色值”(或像素)的一些示例:

First pixel: -6700606 (in HEX: FFFFFFFFFF99C1C2)  
Last pixel: -11449516 (in HEX: FFFFFFFFFF514B54)  
First as colour: [153 193 194] (in HEX: 99 C1 C2)   
Last as colour: [81 75 84] (in HEX: 51 4B 54)   
相反的做法意味着
[153 193 194]
变成
-6700606
。例如,以前有人问过这个问题。以下是我的两次尝试,但都没有成功:

;rgb = 0xFFFF * r + 0xFF * g + b
(defn my-rgb-1 [[r g b]]
  (+ (* 0xFFFF r) (* 0xFF g) b))  

;int rgb = ((r&0x0ff)<<16)|((g&0x0ff)<<8)|(b&0x0ff);
(defn my-rgb-2 [[r g b]]
(let [red (bit-shift-left 16 (bit-and r 0x0FF))
      green (bit-shift-left 8 (bit-and g 0x0FF))
      blue (bit-and b 0x0FF)]
 (bit-or red green blue)))
;rgb=0xFFFF*r+0xFF*g+b
(定义my-rgb-1[[r g b]]
(+(*0xFFFF r)(*0xFFG)b))
;int rgb=((r&0x0ff)图像

步骤1和2正常,但步骤3不正常。如果步骤3正常,则提取的像素与写入像素相同

imagez中有一个
rgb
函数,但它对我也不起作用。(作者更新我说它不应该。请参阅)。我还可以补充一点,imagez函数
get pixel
首先用于获取像素(步骤1),然后是
组件rgb
(步骤2),如上所示


看看我概述的步骤。

如果我正确理解您的问题,您的问题是:

"First pixel" in hex is i.e 0xFFFFFFFFF99C1C2
 you convert it to decimal-rgb via `components-rgb` = [153 193 194]
 you re-convert [153 193 194] to int via `rbg` and get 
  0x99C1C2
which by all means is correct
因为clojure默认使用long,所以您只需要做一件事 使用
未选中的整数
转换为
整数
,如下所示:

(unchecked-int 0xFFFFFFFFFF99C1C2)
-6700606

这就是您想要的-对吗?

我的参数以错误的顺序向左移位。因此,这是改进的
my-rgb-2
的基本版本:

(defn my-rgb-2 [[r g b]]
  (let [red (bit-shift-left r 16)
        green (bit-shift-left g 8)
        blue b]
    (bit-or red green blue)))
我省略了
(位和a 0x0FF)
,(其中a是r、g或b),只是因为只有当数字大于255时才需要它,这无论如何都不是一个合适的值。对于这个答案,它是否存在并不重要

接下来要做的是将所有0xF(全部4位填充)放在开头。这几乎让我达到了目的:

(defn my-rgb-2 [[r g b]]
  (let [red (bit-shift-left (bit-and r 0x0FF) 16)
        green (bit-shift-left (bit-and g 0x0FF) 8)
        blue (bit-and b 0x0FF)]
    (bit-or 0xFFFFFFFFF000000 (bit-or red green blue))))  
不幸的是,如果我在最后一行再加一个0xF,我会得到:

Exception in thread "main" java.lang.IllegalArgumentException: bit operation not supported for: class clojure.lang.BigInt
但这可以通过借用@birdspider给出的答案来解决:

(defn my-rgb-2 [[r g b]]
  (let [red (bit-shift-left (bit-and r 0x0FF) 16)
        green (bit-shift-left (bit-and g 0x0FF) 8)
        blue (bit-and b 0x0FF)]
    (bit-or (bit-or red green blue) (unchecked-int 0xFFFFFFFFFF000000))))

imagez库现在具有此功能,但出于性能原因,可以作为宏来使用。

我建议您发布颜色的十六进制表示法,而不是十进制表示法,这对您和我们来说都会更清楚。您的
my-rgb-2
尝试:注释行是对您想要的颜色的描述?然后您缺少一些
>位左移
s(您执行
位和
s和
位或
s,但决定同时忽略
(格式“0x%x”-6700606)=>“0xFFFFFFFF99C1C2”
在打印位时可能很有用/hex
imagez中有一个rgb函数,但它对我也不起作用。
你能澄清一下吗?看起来和你想要的完全一样?澄清imagez中现有的
rgb
函数对我不起作用。谢谢。查看issue.clj你可以使用任何
现有的rgb
>,
my-rgb-1
my-rgb-2
。上次我查看时,他们都没有返回正确答案。