There are a couple of issues with your question:
- Firstly you are missing a declaration of
validPath
function. I'll assume it does some file path validation, so I'll just ignore it in the answer.
readImage
is an IO
action, as such you can't just pattern match on Either
, you need to execute it first.
- You also need to output the result image somewhere, so you need out path as well
Some more image specific remarks:
- Applying convolution to YCbCr encoded image doesn't really make sense, so you either need to convert to RGB or grayscale Y. I'll assume you want color so we'll use RGB
- You didn't specify which filter you want, so'll just go with gaussian blur
applyFilterJpg :: FilePath -> FilePath -> IO ()
applyFilterJpg fcin fcout = do
eImg <- readImageExact JPG fcin
case eImg of
Left err -> putStrLn err
Right img -> do
let imgRGB :: Image VS RGB Double
imgRGB = convert (img :: Image VS YCbCr Word8)
gaussianBlurKernel :: Image VS X Double
gaussianBlurKernel = fromLists $ [ [ 1/16, 1/8, 1/16 ]
, [ 1/8, 1/4, 1/8 ]
, [ 1/16, 1/8, 1/16 ] ]
convRGB = convolve Edge gaussianBlurKernel imgRGB
writeImage fcout convRGB
This is what we get when we run it:

That being said, there are already functions built in that will simplify this whole process for you:
- Use import functions that already do the conversion for you, so you don't need to mess with manual conversion of color spaces.
- Instead of supplying kernel for filter manually, check see if there is already one available in HIP that you need.
addFilterJpg' :: FilePath -> FilePath -> IO ()
addFilterJpg' fcin fcout = do
imgRGB <- readImageRGB VS fcin
let convRGB = applyFilter (gaussianBlur 1) imgRGB
writeImage fcout convRGB
This is the outcome of the above function:
