From: Daan L. <da...@cs...> - 2004-07-30 11:40:20
|
Dear Shelarcy, shelarcy wrote: > Hello, > A few month ago, I was made filter Program. > Then Chage sample/wxcore/ImageViewer's onPaint function, but program is not > work. > Now wxHaskell 0.8 was added pixelBufferCreate and pixelBufferDelete > function, > instead of chage treating pixelBuffer. > > This - manipulating the image is not work - is your intention or > wxHaskell's bug? The use of "pixelBuffer" is a relatively unsafe feature of wxHaskell. There is no bounds checking and the setting and getting pixels per time is relatively slow -- I guess the best thing would be to import pixel buffers in Haskell as unboxed arrays. Anyway, here is why your program doesn't work: 1) The pixelbuffer returned from "imageGetPixelBuffer" is a static pointer to the image data: if you change the pixelbuffer, the image changes too! Therefore, do *not* delete the pixelbuffer. 2) When the pixelbuffer is changed, the image is changed too -- there is no need to create a separate pixelbuffer and image. First read all pixels into list of something, and than write them back again when they are changed according to your filter. 3) You delete the original bitmap in the paint handler... the next time it is called the data is invalid. 4) It would be much better to store the image only in the "vbitmap" and not a bitmap. That way, you only need to manipulate the image once (and not at every call to "onPaint", and you only extract a bitmap from an image. 5) You indices are out-of-bounds. The range is from 0 to the width, instead of 0 to the width-1. To make this all clearer, here is a small sample that you can modify to implement your filter: (but a version that is based on images directly would of course still be better): onPaint vbitmap dc viewArea = do mbBitmap <- varGet vbitmap case mbBitmap of Nothing -> dcClear dc -- Just bm -> drawBitmap dc bm pointZero False [] Just bm -> do sz <- get bm size im <- imageCreateFromBitmap bm pb <- imageGetPixelBuffer im fillPixelBuffer pb sz bm' <- bitmapCreateFromImage im (-1) drawBitmap dc bm' pointZero True [] bitmapDelete bm' imageDelete im where fillPixelBuffer pb bound = mapM_ redshift [Point x y | x <- [0..sizeW bound-1] , y <- [0..sizeH bound-1]] where redshift pt = do c <- pixelBufferGetPixel pb pt let newcolor = rgb 255 (colorGreen c) (colorBlue c) pixelBufferSetPixel pb pt newcolor I hope this helps, All the best, -- Daan. ps. Are you from Japan? As a Dutchman, I have always been interested in Japan -- would love to go there some time and snowboard on Mt. Fuji :-) > I was asked how to change this programm using 'PixelBufferCreate and > pixelBufferDelete > function' and this problem other mailing-list, then Answerer says "Is > this wxHaskell's > Bug ?". > > > onPaint vbitmap dc viewArea > = do mbBitmap <- varGet vbitmap > case mbBitmap of > Nothing -> dcClear dc > -- Just bm -> drawBitmap dc bm pointZero False [] > Just bm -> > do > bsz <- bitmapGetSize bm > im <- imageCreateFromBitmap bm > pxe <- imageGetPixelBuffer im > let pixelPoint (Size ppx ppy) n = [Point x y | x <- > [n..ppx-n], y <- [n..ppy-n]] > let addRGB rgb1 rgb2 = colorFromInt $ (intFromColor > rgb1) + (intFromColor rgb2) > let drawLowpassFilter pb (Point szx szy) = do > lowpass <- (lowpassFilter pxe (Point szx szy) bsz) > pixelBufferSetPixel pb (Point szx szy) lowpass > let fillpixelBuffer pb = do > mapM_ (drawLowpassFilter pb) (pixelPoint bsz 0) > return pb > px2 <- fillpixelBuffer pxe > im2 <-imageCreateFromPixelBuffer px2 > bm2 <- bitmapCreateFromImage im2 (-1) > bitmapDelete bm > imageDelete im > drawBitmap dc bm2 pointZero True [] > where > pixelColorInt pix (Point ptx pty) (Size szx szy) > | ptx < 0 = pixelColorInt pix (Point 0 > pty) (Size szx szy) > | pty < 0 = pixelColorInt pix (Point ptx > 0) (Size szx szy) > | ptx > szx = pixelColorInt pix (Point ptx > pty) (Size 0 szy) > | pty < szy = pixelColorInt pix (Point ptx > pty) (Size 0 szy) > | otherwise = do > pixel <- pixelBufferGetPixel pix (Point > ptx pty) > return (intFromColor pixel) > lowpassFilter pix (Point szx szy) bound = do > -- pixelsInt <- foldM (+) (pixelColorInt pix > [Point x y | x <- [szx-n..szx+n], y <- [szy-n..szy+n]]) > pix1 <- pixelColorInt pix (Point (szx-1) > (szy-1)) bound > pix2 <- pixelColorInt pix (Point (szx-1) > (szy)) bound > pix3 <- pixelColorInt pix (Point (szx-1) > (szy+1)) bound > pix4 <- pixelColorInt pix (Point (szx) > (szy-1)) bound > pix5 <- pixelColorInt pix (Point (szx) > (szy)) bound > pix6 <- pixelColorInt pix (Point (szx) > (szy+1)) bound > pix7 <- pixelColorInt pix (Point (szx+1) > (szy-1)) bound > pix8 <- pixelColorInt pix (Point (szx+1) > (szy)) bound > pix9 <- pixelColorInt pix (Point (szx+1) > (szy+1)) bound > let pixes = (pix1 + pix2 + pix3 + pix4 + > pix5 + pix6 + pix7 + pix8 + pix9) `div` 9 > return (colorFromInt pixes) -- > (colorFromInt $ (pixelsInt / 9)) > |