JuicyPixels-scale-dct 0.1.1.2 → 0.1.2
raw patch · 5 files changed
+89/−27 lines, 5 filesdep ~JuicyPixelsdep ~basedep ~base-compatPVP ok
version bump matches the API change (PVP)
Dependency ranges changed: JuicyPixels, base, base-compat, time
API changes (from Hackage documentation)
+ Codec.Picture.ScaleDCT: scaleWithKernel :: (Int, Int) -> (Int -> Int -> Double) -> Image PixelRGBA8 -> Image PixelRGBA8
Files
- CHANGELOG.md +4/−0
- JuicyPixels-scale-dct.cabal +12/−16
- README.md +4/−0
- example/Example.hs +17/−7
- src/Codec/Picture/ScaleDCT.hs +52/−4
CHANGELOG.md view
@@ -1,3 +1,7 @@+# 0.1.2++- Add `scaleWithKernel` to convolute the image. Usaful for applyng unsharp mask!+ # 0.1.1.2 - Make test suite pass, even if `cat.jpg` is absent
JuicyPixels-scale-dct.cabal view
@@ -1,23 +1,19 @@--- This file has been generated from package.yaml by hpack version 0.14.0.------ see: https://github.com/sol/hpack- name: JuicyPixels-scale-dct-version: 0.1.1.2+version: 0.1.2 synopsis: Scale JuicyPixels images with DCT description: Scale JuicyPixels Images with DCT . There is also a @friday@ version: <http://hackage.haskell.org/package/friday-scale-dct friday-scale-dct>-category: Web+category: Graphics, Image homepage: https://github.com/phadej/JuicyPixels-scale-dct#readme bug-reports: https://github.com/phadej/JuicyPixels-scale-dct/issues author: Oleg Grenrus <oleg.grenrus@iki.fi> maintainer: Oleg Grenrus <oleg.grenrus@iki.fi> license: BSD3 license-file: LICENSE-tested-with: GHC==7.8.4, GHC==7.10.3, GHC==8.0.1 build-type: Simple-cabal-version: >= 1.10+cabal-version: >=1.10+tested-with: GHC==7.8.4, GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.2 extra-source-files: CHANGELOG.md@@ -33,8 +29,8 @@ src ghc-options: -Wall build-depends:- base >=4.7 && <4.10- , base-compat >=0.6.0 && <0.10+ base >=4.7 && <4.12+ , base-compat >=0.6.0 && <0.11 , JuicyPixels >=3.2.5.3 && <3.3 , fft >=0.1.8.1 && <0.2 , carray >=0.1.6.1 && <0.2@@ -49,13 +45,13 @@ example ghc-options: -Wall build-depends:- base >=4.7 && <4.10- , base-compat >=0.6.0 && <0.10- , JuicyPixels >=3.2.5.3 && <3.3- , fft >=0.1.8.1 && <0.2- , carray >=0.1.6.1 && <0.2+ base+ , base-compat+ , JuicyPixels+ , fft+ , carray , base , JuicyPixels >=3.2.8 , JuicyPixels-scale-dct- , time >=1.4.2 && <1.7+ , time >=1.4.2 && <1.9 default-language: Haskell2010
README.md view
@@ -22,6 +22,10 @@  +### very small+++ ### larger 
example/Example.hs view
@@ -1,29 +1,39 @@ module Main (main) where import Codec.Picture (convertRGBA8, readImage, writePng)-import Codec.Picture.ScaleDCT (scale)+import Codec.Picture.ScaleDCT (scale, scaleWithKernel) import Data.Time (diffUTCTime, getCurrentTime) processImage :: String -- ^ From -> (Int, Int) -- ^ Target size -> String -- ^ To+ -> Maybe (Int -> Int -> Double) -- ^ kernel -> IO ()-processImage src size dst = do+processImage src size dst mk = do+ let scale' = maybe (scale size) (scaleWithKernel size) mk start <- getCurrentTime eimg <- readImage src case eimg of Left err -> print err Right dimg -> do let img = convertRGBA8 dimg- let ava = scale size img+ let ava = scale' img writePng dst ava end <- getCurrentTime putStrLn $ dst ++ ": " ++ show (end `diffUTCTime` start) + main :: IO () main = do- processImage "cat.jpg" (96, 64) "cat-small.png"- processImage "cat.jpg" (769, 512) "cat-large.png"- processImage "phadej.png" (64, 64) "phadej-small.png"- processImage "phadej.png" (600, 600) "phadej-large.png"+ processImage "cat.jpg" (96, 64) "cat-small.png" Nothing+ processImage "cat.jpg" (769, 512) "cat-large.png" Nothing+ processImage "phadej.png" (32, 32) "phadej-smaller.png" (Just k)+ processImage "phadej.png" (64, 64) "phadej-small.png" (Just k)+ processImage "phadej.png" (600, 600) "phadej-large.png" Nothing+ where+ k 0 0 = 2.75 -- make this larger or smaller to adjust amount of an effect.+ k 0 1 = -0.125+ k 1 0 = -0.125+ k 1 1 = -0.0625+ k _ _ = 0
src/Codec/Picture/ScaleDCT.hs view
@@ -10,7 +10,7 @@ -- -- Scale pictures using Discrete Cosine Transform. ---module Codec.Picture.ScaleDCT (scale) where+module Codec.Picture.ScaleDCT (scale, scaleWithKernel) where import Prelude () import Prelude.Compat@@ -24,7 +24,7 @@ import Data.Ix (inRange, range) import Data.Monoid (Endo (..)) import Data.Word (Word8)-import Math.FFT (dct2N, dct3N)+import Math.FFT (dct1N, dct2N, dct3N) type Array2D = CArray (Int, Int) Double @@ -33,8 +33,44 @@ :: (Int, Int) -- ^ Output width, height -> Image PixelRGBA8 -- ^ Input image -> Image PixelRGBA8 -- ^ Output image-scale dim img = fromChannels r' g' b' a'+scale dim = scaleImpl (cut dim)++-- | Scale the image using DCT transform.+--+-- Convolute /result/ image with a symmetric kernel.+-- See <https://en.wikipedia.org/wiki/Symmetric_convolution>+--+-- Identity kernel:+--+-- @+-- k 0 0 = 1+-- k _ _ = 0+-- @+--+-- Sharpen:+--+-- @+-- k 0 0 = 1.75+-- k 0 1 = -0.125+-- k 1 0 = -0.125+-- k 1 1 = -0.0625+-- k _ _ = 0+-- @+--+scaleWithKernel+ :: (Int, Int) -- ^ Output width, height+ -> (Int -> Int -> Double) -- ^ kernel+ -> Image PixelRGBA8 -- ^ Input image+ -> Image PixelRGBA8 -- ^ Output image+scaleWithKernel dim@(w,h) kf = scaleImpl (cutWithKernel dim ker) where+ ker :: Array2D+ ker = dct1N [0, 1] $ array kb [ (i, kf x y) | i@(y, x) <- range kb ]+ kb = ((0, 0), (h-1, w-1))++scaleImpl :: (Array2D -> Array2D) -> Image PixelRGBA8 -> Image PixelRGBA8+scaleImpl cutImpl img = fromChannels r' g' b' a'+ where r = channelR img g = channelG img b = channelB img@@ -42,7 +78,7 @@ transform ch = amap (k*) ch' where- ch' = dct3N [1, 0] . cut dim . dct2N [0, 1] $ ch+ ch' = dct3N [1, 0] . cutImpl . dct2N [0, 1] $ ch k = imgNorm ch / imgNorm ch' r' = transform r@@ -63,6 +99,18 @@ b' = bounds img pick i | inRange b' i = img ! i | otherwise = 0++cutWithKernel :: (Int, Int) -> Array2D -> Array2D -> Array2D+cutWithKernel (w, h) k img = array b [ (i, pick i) | i <- range b ]+ where+ b = ((0,0), (h-1, w-1))+ b' = bounds img+ pick i | inRange b' i = k' i * (img ! i)+ | otherwise = 0++ kb = bounds k+ k' i | inRange kb i = k ! i+ | otherwise = 0 pixelR, pixelG, pixelB, pixelA :: PixelRGBA8 -> Word8 pixelR (PixelRGBA8 r _ _ _) = r