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>
|
<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>
|
|
@ -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()
|
||||||
|
|
||||||
|
|
||||||
|
}
|
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) {
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue