drawImage

This commit is contained in:
legoff.laurent 2010-12-10 17:33:02 +00:00
parent 23c3b81948
commit f23da51ff6
6 changed files with 196 additions and 56 deletions

View file

@ -13,5 +13,6 @@
<canvas id="TestStar" width="400" height="400"></canvas> <canvas id="TestStar" width="400" height="400"></canvas>
<p>TestTransform</p> <p>TestTransform</p>
<canvas id="TestTransform" width="400" height="400"></canvas> <canvas id="TestTransform" width="400" height="400"></canvas>
<canvas id="TestFillRect" width="300" height="300"></canvas>
</body> </body>
</html> </html>

View file

@ -17,6 +17,7 @@ function draw(test){
function executeTests() { function executeTests() {
draw(TestStar) draw(TestStar)
draw(TestTransform) draw(TestTransform)
draw(TestFillRect)
} }
function TestStar(gc) { function TestStar(gc) {
@ -82,3 +83,21 @@ function TestTransform(gc) {
gc.stroke() gc.stroke()
gc.restore() 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()
}

View 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)
}

View file

@ -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) { func arcAdder(adder raster.Adder, x, y, rx, ry, start, angle, scale float) raster.Point {
end := start + angle end := start + angle
clockWise := true clockWise := true
if angle < 0 { if angle < 0 {
clockWise = false clockWise = false
} }
ra := (fabs(rx) + fabs(ry)) / 2 ra := (fabs(rx) + fabs(ry)) / 2
da := acos(ra/(ra+0.125/scale)) * 2 da := acos(ra/(ra+0.125/scale)) * 2
//normalize //normalize
if !clockWise { if !clockWise {
da = -da da = -da
} }
angle = start + da angle = start + da
var curX, curY float var curX, curY float
for { for {
if (angle < end-da/4) != clockWise { if (angle < end-da/4) != clockWise {
curX = x + cos(end)*rx curX = x + cos(end)*rx
curY = y + sin(end)*ry curY = y + sin(end)*ry
return floatToPoint(curX, curY) return floatToPoint(curX, curY)
} }
curX = x + cos(angle)*rx curX = x + cos(angle)*rx
curY = y + sin(angle)*ry curY = y + sin(angle)*ry
angle += da angle += da
adder.Add1(floatToPoint(curX, curY)) adder.Add1(floatToPoint(curX, curY))
} }
return floatToPoint(curX, curY) return floatToPoint(curX, curY)
} }

View file

@ -77,6 +77,10 @@ func NewGraphicContext(pi *image.RGBA) *GraphicContext {
return gc return gc
} }
func (gc *GraphicContext) GetMatrixTransform() (tr MatrixTransform) {
return gc.current.tr
}
func (gc *GraphicContext) SetMatrixTransform(tr MatrixTransform) { func (gc *GraphicContext) SetMatrixTransform(tr MatrixTransform) {
gc.current.tr = tr 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() { func (gc *GraphicContext) BeginPath() {
gc.current.path = new(PathStorage) gc.current.path = new(PathStorage)
} }

View file

@ -37,52 +37,51 @@ func (vertexAdder *VertexAdder) Vertex(x, y float) {
type PathAdder struct { type PathAdder struct {
adder raster.Adder adder raster.Adder
lastPoint raster.Point lastPoint raster.Point
ApproximationScale float ApproximationScale float
} }
func NewPathAdder(adder raster.Adder) (* PathAdder) { func NewPathAdder(adder raster.Adder) *PathAdder {
return &PathAdder{adder, raster.Point{0,0}, 1} return &PathAdder{adder, raster.Point{0, 0}, 1}
} }
func (pathAdder *PathAdder) Convert(paths ...*PathStorage) { func (pathAdder *PathAdder) Convert(paths ...*PathStorage) {
for _, path := range paths { for _, path := range paths {
j := 0 j := 0
for _, cmd := range path.commands { for _, cmd := range path.commands {
j = j + pathAdder.ConvertCommand(cmd, path.vertices[j:]...) j = j + pathAdder.ConvertCommand(cmd, path.vertices[j:]...)
} }
} }
} }
func (pathAdder *PathAdder) ConvertCommand(cmd PathCmd, vertices ...float) int { func (pathAdder *PathAdder) ConvertCommand(cmd PathCmd, vertices ...float) int {
switch cmd { switch cmd {
case MoveTo: case MoveTo:
pathAdder.lastPoint = floatToPoint(vertices[0], vertices[1]) pathAdder.lastPoint = floatToPoint(vertices[0], vertices[1])
pathAdder.adder.Start(pathAdder.lastPoint) pathAdder.adder.Start(pathAdder.lastPoint)
return 2 return 2
case LineTo: case LineTo:
pathAdder.lastPoint = floatToPoint(vertices[0], vertices[1]) pathAdder.lastPoint = floatToPoint(vertices[0], vertices[1])
pathAdder.adder.Add1(pathAdder.lastPoint) pathAdder.adder.Add1(pathAdder.lastPoint)
return 2 return 2
case QuadCurveTo: case QuadCurveTo:
pathAdder.lastPoint = floatToPoint(vertices[2], vertices[3]) pathAdder.lastPoint = floatToPoint(vertices[2], vertices[3])
pathAdder.adder.Add2(floatToPoint(vertices[0], vertices[1]), pathAdder.lastPoint) pathAdder.adder.Add2(floatToPoint(vertices[0], vertices[1]), pathAdder.lastPoint)
return 4 return 4
case CubicCurveTo: case CubicCurveTo:
pathAdder.lastPoint = floatToPoint(vertices[4], vertices[5]) pathAdder.lastPoint = floatToPoint(vertices[4], vertices[5])
pathAdder.adder.Add3(floatToPoint(vertices[0], vertices[1]), floatToPoint(vertices[2], vertices[3]), pathAdder.lastPoint) pathAdder.adder.Add3(floatToPoint(vertices[0], vertices[1]), floatToPoint(vertices[2], vertices[3]), pathAdder.lastPoint)
return 6 return 6
case ArcTo: case ArcTo:
pathAdder.lastPoint = arcAdder(pathAdder.adder,vertices[0], vertices[1], vertices[2], vertices[3], vertices[4], vertices[5], pathAdder.ApproximationScale) pathAdder.lastPoint = arcAdder(pathAdder.adder, vertices[0], vertices[1], vertices[2], vertices[3], vertices[4], vertices[5], pathAdder.ApproximationScale)
pathAdder.adder.Add1(pathAdder.lastPoint) pathAdder.adder.Add1(pathAdder.lastPoint)
return 6 return 6
case Close: case Close:
pathAdder.adder.Add1(pathAdder.lastPoint) pathAdder.adder.Add1(pathAdder.lastPoint)
return 0 return 0
} }
return 0 return 0
} }