请在2024 Clojure 状态调查!分享您的想法。

欢迎!有关如何使用本站的信息,请参阅关于页面。

0
编译器
编辑

我们使用 org.apache.batik 将 svg 字符串渲染为图像。为了设置我们得到图像的质量,我们代理 org.apache.batik.transcoder.image.PNGTranscoder,以便可以对返回的渲染应用一些图像渲染设置。方法 createRenderer 是抽象类 org.apache.batik.transcoder.image.ImageTranscoder 上的受保护方法,PNGTranscoder 是由此扩展的。

完整代码如下

(set! *warn-on-reflection* true)
(defn- high-quality-png-transcoder ^PNGTranscoder []
  (proxy [PNGTranscoder] []
    (createRenderer []
      (let [add-hint                (fn [^RenderingHints hints k v] (.add hints (RenderingHints. k v)))
            ^ImageRenderer renderer (proxy-super createRenderer) ;; line 104
            hints                   (RenderingHints.
                                     RenderingHints/KEY_ALPHA_INTERPOLATION
                                     RenderingHints/VALUE_ALPHA_INTERPOLATION_QUALITY)]
        (doto hints
          (add-hint RenderingHints/KEY_ALPHA_INTERPOLATION RenderingHints/VALUE_ALPHA_INTERPOLATION_QUALITY)
          (add-hint RenderingHints/KEY_INTERPOLATION       RenderingHints/VALUE_INTERPOLATION_BICUBIC)
          (add-hint RenderingHints/KEY_ANTIALIASING        RenderingHints/VALUE_ANTIALIAS_ON)
          (add-hint RenderingHints/KEY_COLOR_RENDERING     RenderingHints/VALUE_COLOR_RENDER_QUALITY)
          (add-hint RenderingHints/KEY_DITHERING           RenderingHints/VALUE_DITHER_DISABLE)
          (add-hint RenderingHints/KEY_RENDERING           RenderingHints/VALUE_RENDER_QUALITY)
          (add-hint RenderingHints/KEY_STROKE_CONTROL      RenderingHints/VALUE_STROKE_PURE)
          (add-hint RenderingHints/KEY_FRACTIONALMETRICS   RenderingHints/VALUE_FRACTIONALMETRICS_ON)
          (add-hint RenderingHints/KEY_TEXT_ANTIALIASING   RenderingHints/VALUE_TEXT_ANTIALIAS_OFF))
        (.setRenderingHints renderer hints)
        renderer))))

这会产生警告

反射警告,metabase/pulse/render/poc.clj:104:37 - 无法解析字段创建Renderer的引用。

Clojure 文档提供了 "typehint this" 解决方案。在 proxy-super 上面添加 ^PNGTranscoder this this 并没有解决问题,只是表明代码有更多信息。

反射警告,metabase/pulse/render/poc.clj:105:37 - 无法解析在 org.apache.batik.transcoder.image.PNGTranscoder 中的字段 createRenderer 的引用。

(第 104 行因为在新的类型提示的 this 绑定中变为第 105 行)

1 个答案

+1

在 PNGTranscoder 中,createRenderer 方法是受保护的,但在生成的代理类中是公开的,因此除非用代理类的具体类型来提示 this(这是一种非常规的方法,但可能技术上可行),否则无法非反射地调用它,但通过反射调用它,它使用代理的运行时类型,因此可以访问该方法,效果良好。

...