drawImage
This commit is contained in:
parent
23c3b81948
commit
f23da51ff6
6 changed files with 196 additions and 56 deletions
|
@ -13,5 +13,6 @@
|
|||
<canvas id="TestStar" width="400" height="400"></canvas>
|
||||
<p>TestTransform</p>
|
||||
<canvas id="TestTransform" width="400" height="400"></canvas>
|
||||
<canvas id="TestFillRect" width="300" height="300"></canvas>
|
||||
</body>
|
||||
</html>
|
|
@ -17,6 +17,7 @@ function draw(test){
|
|||
function executeTests() {
|
||||
draw(TestStar)
|
||||
draw(TestTransform)
|
||||
draw(TestFillRect)
|
||||
}
|
||||
|
||||
function TestStar(gc) {
|
||||
|
@ -82,3 +83,21 @@ function TestTransform(gc) {
|
|||
gc.stroke()
|
||||
gc.restore()
|
||||
}
|
||||
function TestFillRect(gc) {
|
||||
gc.moveTo(95,95)
|
||||
gc.lineTo(195,95)
|
||||
gc.lineTo(195, 195)
|
||||
gc.lineTo(95, 195)
|
||||
gc.lineTo(95, 95)
|
||||
|
||||
|
||||
gc.moveTo(105,105)
|
||||
gc.lineTo(105, 205)
|
||||
gc.lineTo(205, 205)
|
||||
gc.lineTo(205,105)
|
||||
gc.lineTo(105, 105)
|
||||
|
||||
gc.fill()
|
||||
|
||||
|
||||
}
|
82
draw2d/src/cmd/testimage.go
Normal file
82
draw2d/src/cmd/testimage.go
Normal file
|
@ -0,0 +1,82 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"bufio"
|
||||
"math"
|
||||
"image"
|
||||
"time"
|
||||
"image/png"
|
||||
"draw2d"
|
||||
//"draw2d.googlecode.com/svn/trunk/draw2d/src/pkg/draw2d"
|
||||
)
|
||||
|
||||
|
||||
func saveToPngFile(filePath string, m image.Image) {
|
||||
f, err := os.Open(filePath, os.O_CREAT|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer f.Close()
|
||||
b := bufio.NewWriter(f)
|
||||
err = png.Encode(b, m)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
err = b.Flush()
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("Wrote %s OK.\n", filePath)
|
||||
}
|
||||
|
||||
func loadFromPngFile(filePath string) image.Image {
|
||||
f, err := os.Open(filePath, 0, 0)
|
||||
if f == nil {
|
||||
log.Printf("can't open file; err=%s\n", err.String())
|
||||
return nil
|
||||
}
|
||||
defer f.Close()
|
||||
b := bufio.NewReader(f)
|
||||
i, err := png.Decode(b)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("Read %s OK.\n", filePath)
|
||||
return i
|
||||
}
|
||||
|
||||
|
||||
func testBubble(gc * draw2d.GraphicContext) {
|
||||
gc.BeginPath()
|
||||
gc.MoveTo(75, 25)
|
||||
gc.QuadCurveTo(25, 25, 25, 62.5)
|
||||
gc.QuadCurveTo(25, 100, 50, 100)
|
||||
gc.QuadCurveTo(50, 120, 30, 125)
|
||||
gc.QuadCurveTo(60, 120, 65, 100)
|
||||
gc.QuadCurveTo(125, 100, 125, 62.5)
|
||||
gc.QuadCurveTo(125, 25, 75, 25)
|
||||
gc.Stroke()
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
|
||||
source := loadFromPngFile("../../Varna_Railway_Station_HDR.png")
|
||||
i := image.NewRGBA(1024, 768)
|
||||
gc := draw2d.NewGraphicContext(i)
|
||||
gc.Scale(2, 0.5)
|
||||
//gc.Translate(75, 25)
|
||||
gc.Rotate(30 * math.Pi/180)
|
||||
lastTime := time.Nanoseconds()
|
||||
gc.DrawImage(source)
|
||||
dt := time.Nanoseconds() - lastTime
|
||||
fmt.Printf("Draw image: %f ms\n", float(dt)*1e-6)
|
||||
saveToPngFile("../../TestDrawImage.png", i)
|
||||
}
|
|
@ -36,32 +36,31 @@ func arc(t VertexConverter, x, y, rx, ry, start, angle, scale float) (lastX, las
|
|||
}
|
||||
|
||||
|
||||
func arcAdder(adder raster.Adder, x, y, rx, ry, start, angle, scale float) (raster.Point) {
|
||||
end := start + angle
|
||||
clockWise := true
|
||||
if angle < 0 {
|
||||
clockWise = false
|
||||
}
|
||||
ra := (fabs(rx) + fabs(ry)) / 2
|
||||
da := acos(ra/(ra+0.125/scale)) * 2
|
||||
//normalize
|
||||
if !clockWise {
|
||||
da = -da
|
||||
}
|
||||
angle = start + da
|
||||
var curX, curY float
|
||||
for {
|
||||
if (angle < end-da/4) != clockWise {
|
||||
curX = x + cos(end)*rx
|
||||
curY = y + sin(end)*ry
|
||||
return floatToPoint(curX, curY)
|
||||
}
|
||||
curX = x + cos(angle)*rx
|
||||
curY = y + sin(angle)*ry
|
||||
func arcAdder(adder raster.Adder, x, y, rx, ry, start, angle, scale float) raster.Point {
|
||||
end := start + angle
|
||||
clockWise := true
|
||||
if angle < 0 {
|
||||
clockWise = false
|
||||
}
|
||||
ra := (fabs(rx) + fabs(ry)) / 2
|
||||
da := acos(ra/(ra+0.125/scale)) * 2
|
||||
//normalize
|
||||
if !clockWise {
|
||||
da = -da
|
||||
}
|
||||
angle = start + da
|
||||
var curX, curY float
|
||||
for {
|
||||
if (angle < end-da/4) != clockWise {
|
||||
curX = x + cos(end)*rx
|
||||
curY = y + sin(end)*ry
|
||||
return floatToPoint(curX, curY)
|
||||
}
|
||||
curX = x + cos(angle)*rx
|
||||
curY = y + sin(angle)*ry
|
||||
|
||||
angle += da
|
||||
adder.Add1(floatToPoint(curX, curY))
|
||||
}
|
||||
angle += da
|
||||
adder.Add1(floatToPoint(curX, curY))
|
||||
}
|
||||
return floatToPoint(curX, curY)
|
||||
}
|
||||
|
||||
|
|
|
@ -77,6 +77,10 @@ func NewGraphicContext(pi *image.RGBA) *GraphicContext {
|
|||
return gc
|
||||
}
|
||||
|
||||
func (gc *GraphicContext) GetMatrixTransform() (tr MatrixTransform) {
|
||||
return gc.current.tr
|
||||
}
|
||||
|
||||
func (gc *GraphicContext) SetMatrixTransform(tr MatrixTransform) {
|
||||
gc.current.tr = tr
|
||||
}
|
||||
|
@ -188,6 +192,42 @@ func (gc *GraphicContext) Restore() {
|
|||
}
|
||||
}
|
||||
|
||||
func (gc *GraphicContext) DrawImage(image image.Image) {
|
||||
width := raster.Fix32(gc.PaintedImage.Bounds().Dx()* 256)
|
||||
height := raster.Fix32(gc.PaintedImage.Bounds().Dy()* 256)
|
||||
|
||||
painter := raster.NewRGBAPainter(gc.PaintedImage)
|
||||
|
||||
p0 := raster.Point{0,0}
|
||||
p1 := raster.Point{0,0}
|
||||
p2 := raster.Point{0,0}
|
||||
p3 := raster.Point{0,0}
|
||||
var i raster.Fix32 = 0
|
||||
for ; i < width; i+=256 {
|
||||
var j raster.Fix32 = 0
|
||||
for ; j < height; j+=256 {
|
||||
p0.X, p0.Y = i, j
|
||||
p1.X, p1.Y = p0.X + 256, p0.Y
|
||||
p2.X, p2.Y = p1.X, p0.Y + 256
|
||||
p3.X, p3.Y = p0.X, p2.Y
|
||||
|
||||
gc.current.tr.TransformRasterPoint(&p0, &p1, &p2, &p3)
|
||||
gc.fillRasterizer.Start(p0)
|
||||
gc.fillRasterizer.Add1(p1)
|
||||
gc.fillRasterizer.Add1(p2)
|
||||
gc.fillRasterizer.Add1(p3)
|
||||
gc.fillRasterizer.Add1(p0)
|
||||
painter.SetColor(image.At(int(i>>8), int(j>>8)))
|
||||
gc.fillRasterizer.Rasterize(painter)
|
||||
gc.fillRasterizer.Clear()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (gc *GraphicContext) LastPoint() (x, y float) {
|
||||
return gc.current.path.LastPoint()
|
||||
}
|
||||
|
||||
func (gc *GraphicContext) BeginPath() {
|
||||
gc.current.path = new(PathStorage)
|
||||
}
|
||||
|
|
|
@ -37,52 +37,51 @@ func (vertexAdder *VertexAdder) Vertex(x, y float) {
|
|||
|
||||
|
||||
type PathAdder struct {
|
||||
adder raster.Adder
|
||||
lastPoint raster.Point
|
||||
adder raster.Adder
|
||||
lastPoint raster.Point
|
||||
ApproximationScale float
|
||||
}
|
||||
|
||||
func NewPathAdder(adder raster.Adder) (* PathAdder) {
|
||||
return &PathAdder{adder, raster.Point{0,0}, 1}
|
||||
func NewPathAdder(adder raster.Adder) *PathAdder {
|
||||
return &PathAdder{adder, raster.Point{0, 0}, 1}
|
||||
}
|
||||
|
||||
|
||||
func (pathAdder *PathAdder) Convert(paths ...*PathStorage) {
|
||||
for _, path := range paths {
|
||||
j := 0
|
||||
for _, cmd := range path.commands {
|
||||
j = j + pathAdder.ConvertCommand(cmd, path.vertices[j:]...)
|
||||
}
|
||||
}
|
||||
for _, path := range paths {
|
||||
j := 0
|
||||
for _, cmd := range path.commands {
|
||||
j = j + pathAdder.ConvertCommand(cmd, path.vertices[j:]...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (pathAdder *PathAdder) ConvertCommand(cmd PathCmd, vertices ...float) int {
|
||||
switch cmd {
|
||||
case MoveTo:
|
||||
switch cmd {
|
||||
case MoveTo:
|
||||
pathAdder.lastPoint = floatToPoint(vertices[0], vertices[1])
|
||||
pathAdder.adder.Start(pathAdder.lastPoint)
|
||||
return 2
|
||||
case LineTo:
|
||||
pathAdder.adder.Start(pathAdder.lastPoint)
|
||||
return 2
|
||||
case LineTo:
|
||||
pathAdder.lastPoint = floatToPoint(vertices[0], vertices[1])
|
||||
pathAdder.adder.Add1(pathAdder.lastPoint)
|
||||
return 2
|
||||
case QuadCurveTo:
|
||||
pathAdder.adder.Add1(pathAdder.lastPoint)
|
||||
return 2
|
||||
case QuadCurveTo:
|
||||
pathAdder.lastPoint = floatToPoint(vertices[2], vertices[3])
|
||||
pathAdder.adder.Add2(floatToPoint(vertices[0], vertices[1]), pathAdder.lastPoint)
|
||||
return 4
|
||||
case CubicCurveTo:
|
||||
pathAdder.adder.Add2(floatToPoint(vertices[0], vertices[1]), pathAdder.lastPoint)
|
||||
return 4
|
||||
case CubicCurveTo:
|
||||
pathAdder.lastPoint = floatToPoint(vertices[4], vertices[5])
|
||||
pathAdder.adder.Add3(floatToPoint(vertices[0], vertices[1]), floatToPoint(vertices[2], vertices[3]), pathAdder.lastPoint)
|
||||
return 6
|
||||
case ArcTo:
|
||||
pathAdder.lastPoint = arcAdder(pathAdder.adder,vertices[0], vertices[1], vertices[2], vertices[3], vertices[4], vertices[5], pathAdder.ApproximationScale)
|
||||
return 6
|
||||
case ArcTo:
|
||||
pathAdder.lastPoint = arcAdder(pathAdder.adder, vertices[0], vertices[1], vertices[2], vertices[3], vertices[4], vertices[5], pathAdder.ApproximationScale)
|
||||
pathAdder.adder.Add1(pathAdder.lastPoint)
|
||||
return 6
|
||||
case Close:
|
||||
return 6
|
||||
case Close:
|
||||
pathAdder.adder.Add1(pathAdder.lastPoint)
|
||||
return 0
|
||||
}
|
||||
return 0
|
||||
return 0
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue