I have a little program in haskell, using wxhaskell. It displays a window with a panel inside, containing some drawings. The problem is that the window shrinks to a very tiny size, and I have to expand it with the mouse.
How can I define correctly the size?
here is my program:
module Main where
import Graphics.UI.WX
import Graphics.UI.WXCore
main :: IO ()
main
= start hello
hello :: IO ()
hello = do
f <- frame [text := "HELLO!"]
sw <- panel f [ on paint := onpaint]
set f [clientSize := sz 300 300,
layout := fill $ widget sw]
return()
where
onpaint dc pnel = do
circle dc (pt 200 200) 20 [penKind := PenDash DashDot]
drawPoint dc (pt 200 200) []
thank you.
Setting a minimum size instead of the client size
set f [ layout := minsize (sz 300 300) $ widget sw ]
works for me.
Related
grl <- promoters(TxDb.Celegans.UCSC.ce11.ensGene)
intestine_gr <- makeGRangesFromDataFrame(intestine, keep.extra.columns = TRUE)
mat1 = normalizeToMatrix(intestine_gr, grl, extend = 5000, mean_mode = "w0", w = 50)
mat1:
Normalize intestine_gr to grl:
Upstream 5000 bp (100 windows)
Downstream 5000 bp (100 windows)
Include target regions (44 windows)
61451 target regions
I try to do a matrix for plotting a EnrichHeatmap but with the command normalizeToMatrix I have a matrix with only zero (when I plot the EnrichHeatmap is white) and I don't understand which is the problem, can someone help me?
So I'm making some rgba images pixel by pixel following a certain pattern and saving them as png later on and noticed that when alpha channel es changed with certain colors it changes the whole pixel color when stored as png.
I made a test to show what is currently happening:
img := image.NewRGBA(image.Rect(0, 0, 250, 250))
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
f.Read(b)
img.SetRGBA(x, y, color.RGBA{
249,
214,
133,
255,
})
}
}
var buff bytes.Buffer
err := png.Encode(&buff, img)
if err != nil {
log.Println(err)
return
}
This will print an image of color #F9D685. But if I change alpha into 200 it will print another one with #6844BC and transparency instead of printing the original color with it's transparency.
Is there a way to solve this? I believe that it's because I'm missing something but can't really figure it out and didn't find anything similar to what's happening to me on google/here.
That one is simple:
go doc color.RGBA
package color // import "image/color"
type RGBA struct {
R, G, B, A uint8
}
RGBA represents a traditional 32-bit alpha-premultiplied color, having 8
bits for each of red, green, blue and alpha.
An alpha-premultiplied color component C has been scaled by alpha (A), so
has valid values 0 <= C <= A.
You might be looking for color.NRGBA.
(Always, really always, consult the documentation of the involved types and functions. Always.)
I've looked around but can't find anything useful for drawing circles in golang.
I'd like to draw a draw with 2 given (inner and outer) radius and color all pixels in between.
One possible method would be to iterate through each pixel and color it until the ring has been created. Although, that seems really inefficient.
Any help on this would be greatly appreciated! :)
Please read this related question: Draw a rectangle in Golang?
To sum it up: the standard Go library does not provide primitive drawing or painting capabilities.
So yes, either you have to use a 3rd party library to draw a circle (such as github.com/llgcode/draw2d), or you have to do it yourself. Don't worry, it's not hard at all.
Drawing a single circle
First pick a circle drawing algorithm which is simple and efficient. I recommend the Midpoint circle algorithm.
You will find the algorithm on the linked Wikipedia page. Note: you do not have to understand it if you want to use it.
But we do need to implement the algorithm in Go. Which is rather simple:
func drawCircle(img draw.Image, x0, y0, r int, c color.Color) {
x, y, dx, dy := r-1, 0, 1, 1
err := dx - (r * 2)
for x > y {
img.Set(x0+x, y0+y, c)
img.Set(x0+y, y0+x, c)
img.Set(x0-y, y0+x, c)
img.Set(x0-x, y0+y, c)
img.Set(x0-x, y0-y, c)
img.Set(x0-y, y0-x, c)
img.Set(x0+y, y0-x, c)
img.Set(x0+x, y0-y, c)
if err <= 0 {
y++
err += dy
dy += 2
}
if err > 0 {
x--
dx += 2
err += dx - (r * 2)
}
}
}
That's all it takes. Just pass a draw.Image you want to draw on, and the parameters of the circle you want to draw (center point, radius and the color).
Let's see it in action. Let's create an image, draw a circle on it, and save the image to a file. This is all it takes:
img := image.NewRGBA(image.Rect(0, 0, 100, 100))
drawCircle(img, 40, 40, 30, color.RGBA{255, 0, 0, 255})
buf := &bytes.Buffer{}
if err := png.Encode(buf, img); err != nil {
panic(err)
}
if err := ioutil.WriteFile("circle.png", buf.Bytes(), 0666); err != nil {
panic(err)
}
Note: you could also encode the image directly to an os.File and "skip" the in-memory buffer. This is just for demonstration, and to verify our implementation works.
Drawing a ring (filling space between 2 circles)
This one isn't that trivial if you want to implement it yourself, but using a 3rd party lib here could really come handy.
Although most of them don't contain ring-painting support, they do have circle drawing support, and you can set the width of the line used to draw the circle.
So, set the line width to the value that is the difference of the 2 radius of your circles. And draw a circle with a new radius that is the arithmetic center of the 2 original radius.
Here's the algorithm (this is not runnable code):
// Helper functions abstracting the library you choose:
func setColor(c color.Color) {}
func setLineWidth(width float64) {}
func drawCircle(r, x, y float64) {}
// fillRing draws a ring, where r1 and r2 are 2 concentric circles,
// the boundaries of the ring, (x, y) being the center point.
func fillRing(r1, r2, x, y float64, c color.color) {
// Set drawing color:
setColor(c)
// Set line width:
width := r2 - r1
if width < 0 {
width = -width
}
setLineWidth(width)
// And finally draw a circle which will be a ring:
r := (r2 + r1) / 2
drawCircle(r, x, y)
}
I am trying to draw over an image using a template, the template image is the following
I want to colorize the image red, green, blue and yellow colors with custom colors and achieve something like this:
In order to achieve this I currently use this image as a base
And then draw over the template using draw.Draw(outfitImage, outfitImage.Bounds(), generatorImage, image.ZP, draw.Over)
This however gives a very weird result (nothing near the expected result), this is how I replace pixels
func paintPixels(img *image.NRGBA, base color.Color, dst color.Color) {
br, bg, bb, ba := base.RGBA()
dr, dg, db, _ := dst.RGBA()
for x := 0; x < img.Bounds().Dx(); x++ {
for y := 0; y < img.Bounds().Dy(); y++ {
r, g, b, a := img.At(x, y).RGBA()
if br == r && bg == g && bb == b && ba == a {
img.Set(x, y, color.RGBA{uint8(dr), uint8(dg), uint8(db), 255})
}
}
}
}
The result can vary depending on the alpha value I use when colorizing the image template. So I cant think of a way to achieve the expected result, I guess I should use a mask with draw.DrawMask but I have no clue where to start or how to achieve the result I am looking for
You look like you're just replacing pixels with the colour if all components match. If you look at the compositing methods in bild/blend you should find one that suits you for combining images - you probably want Opacity or Multiply modes and could extract code from this file:
https://github.com/anthonynsimon/bild/blob/master/blend/blend.go
Is there a simple complete code example using any gui toolkit (that will work in both Linux and Windows) of opening multiple opengl windows simultaneously? And how to handle their events and such separately of course. I tried it naively and it crashes.
I received a full working source code example from someone outside of stackoverflow. I'm pasting it here for all to benefit.
module Main where
import Graphics.UI.GLUT
import System.Exit (exitWith, ExitCode(ExitSuccess))
reshape :: ReshapeCallback
reshape size = do
viewport $= (Position 0 0, size)
matrixMode $= Projection
loadIdentity
frustum (-1) 1 (-1) 1 1.5 20
matrixMode $= Modelview 0
keyboard :: KeyboardMouseCallback
keyboard (Char '\27') Down _ _ = exitWith ExitSuccess
keyboard _ _ _ _ = return ()
renderCube :: Color3 GLfloat -> IO ()
renderCube c = do
clear [ ColorBuffer ]
let color3f = color :: Color3 GLfloat -> IO ()
scalef = scale :: GLfloat -> GLfloat -> GLfloat -> IO ()
color3f c
loadIdentity
lookAt (Vertex3 0 0 5) (Vertex3 0 0 0) (Vector3 0 1 0)
scalef 1 2 1
renderObject Wireframe (Cube 1)
flush
displayR :: DisplayCallback
displayR = renderCube (Color3 1 0 0)
displayB :: DisplayCallback
displayB = renderCube (Color3 0 0 1)
createWindowWithDisplayFunc :: String -> Position -> DisplayCallback -> IO Window
createWindowWithDisplayFunc name pos display = do
win <- createWindow name
windowPosition $= pos
clearColor $= Color4 0 0 0 0
shadeModel $= Flat
displayCallback $= display
reshapeCallback $= Just reshape
keyboardMouseCallback $= Just keyboard
return win
main = do
getArgsAndInitialize
initialDisplayMode $= [ SingleBuffered, RGBMode ]
initialWindowSize $= Size 100 100
initialWindowPosition $= Position 100 100
createWindowWithDisplayFunc "R" (Position 10 10) displayR
createWindowWithDisplayFunc "B" (Position 110 10) displayB
mainLoop
GLUT, of course.
The GLUT homepage states
The toolkit supports:
- Multiple windows for OpenGL rendering
- Callback driven event processing
- Sophisticated input devices
- An 'idle' routine and timers
- A simple, cascading pop-up menu facility
- Utility routines to generate various solid and wire frame objects
- Support for bitmap and stroke fonts
- Miscellaneous window management functions
Hence you can use GLUT for managing multiple windows (I had used once). Here is a tutorial for what you need.
I've also found this article which you may look a little, since it's Haskell specific.
OpenGL support in wxWidgets uses the WxGLCanvas class, which is in wxcore as GLCanvas. Unfortunately, it doesn't seem to exist in the wx package. You can probably implement your own control for GLCanvas without too much difficulty, using the other controls in the wx package and C++ usage examples as a reference.