github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/image/draw/draw.go (about)

     1  // Copyright 2014 <chaishushan{AT}gmail.com>. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package draw provides image composition functions.
     6  package draw
     7  
     8  import (
     9  	"image"
    10  	"image/draw"
    11  
    12  	image_ext "github.com/chai2010/gopkg/image"
    13  )
    14  
    15  // Draw aligns r.Min in dst with sp in src and then replaces the rectangle r in dst with src.
    16  func Draw(dst draw.Image, r image.Rectangle, src image.Image, sp image.Point) {
    17  	r0 := r.Intersect(dst.Bounds()).Sub(r.Min)
    18  	r1 := image.Rect(sp.X, sp.Y, sp.X+r.Dx(), sp.Y+r.Dy()).Intersect(src.Bounds()).Sub(sp)
    19  	r = r0.Intersect(r1).Add(r.Min)
    20  
    21  	switch dst := dst.(type) {
    22  	case *image.Gray:
    23  		drawGray(dst, r, src, sp)
    24  	case *image.Gray16:
    25  		drawGray16(dst, r, src, sp)
    26  	case *image_ext.Gray32f:
    27  		drawGray32f(dst, r, src, sp)
    28  	case *image_ext.RGB:
    29  		drawRGB(dst, r, src, sp)
    30  	case *image_ext.RGB48:
    31  		drawRGB48(dst, r, src, sp)
    32  	case *image_ext.RGB96f:
    33  		drawRGB96f(dst, r, src, sp)
    34  	case *image.RGBA:
    35  		drawRGBA(dst, r, src, sp)
    36  	case *image.RGBA64:
    37  		drawRGBA64(dst, r, src, sp)
    38  	case *image_ext.RGBA128f:
    39  		drawRGBA128f(dst, r, src, sp)
    40  	default:
    41  		drawImage(dst, r, src, sp)
    42  	}
    43  }
    44  
    45  func drawGray(dst *image.Gray, r image.Rectangle, src image.Image, sp image.Point) {
    46  	switch src := src.(type) {
    47  	case *image.Gray:
    48  		for y := r.Min.Y; y < r.Max.Y; y++ {
    49  			off0 := dst.PixOffset(r.Min.X, y)
    50  			off1 := src.PixOffset(sp.X, y-r.Min.Y+sp.Y)
    51  			copy(dst.Pix[off0:][:r.Dx()], src.Pix[off1:])
    52  		}
    53  	default:
    54  		drawImage(dst, r, src, sp)
    55  	}
    56  }
    57  
    58  func drawGray16(dst *image.Gray16, r image.Rectangle, src image.Image, sp image.Point) {
    59  	switch src := src.(type) {
    60  	case *image.Gray16:
    61  		for y := r.Min.Y; y < r.Max.Y; y++ {
    62  			off0 := dst.PixOffset(r.Min.X, y)
    63  			off1 := src.PixOffset(sp.X, y-r.Min.Y+sp.Y)
    64  			copy(dst.Pix[off0:][:r.Dx()*2], src.Pix[off1:])
    65  		}
    66  	default:
    67  		drawImage(dst, r, src, sp)
    68  	}
    69  }
    70  
    71  func drawGray32f(dst *image_ext.Gray32f, r image.Rectangle, src image.Image, sp image.Point) {
    72  	switch src := src.(type) {
    73  	case *image_ext.Gray32f:
    74  		for y := r.Min.Y; y < r.Max.Y; y++ {
    75  			off0 := dst.PixOffset(r.Min.X, y)
    76  			off1 := src.PixOffset(sp.X, y-r.Min.Y+sp.Y)
    77  			copy(dst.Pix[off0:][:r.Dx()*4], src.Pix[off1:])
    78  		}
    79  	default:
    80  		drawImage(dst, r, src, sp)
    81  	}
    82  }
    83  
    84  func drawRGB(dst *image_ext.RGB, r image.Rectangle, src image.Image, sp image.Point) {
    85  	switch src := src.(type) {
    86  	case *image_ext.RGB:
    87  		for y := r.Min.Y; y < r.Max.Y; y++ {
    88  			off0 := dst.PixOffset(r.Min.X, y)
    89  			off1 := src.PixOffset(sp.X, y-r.Min.Y+sp.Y)
    90  			copy(dst.Pix[off0:][:r.Dx()*3], src.Pix[off1:])
    91  		}
    92  	default:
    93  		drawImage(dst, r, src, sp)
    94  	}
    95  }
    96  
    97  func drawRGB48(dst *image_ext.RGB48, r image.Rectangle, src image.Image, sp image.Point) {
    98  	switch src := src.(type) {
    99  	case *image_ext.RGB48:
   100  		for y := r.Min.Y; y < r.Max.Y; y++ {
   101  			off0 := dst.PixOffset(r.Min.X, y)
   102  			off1 := src.PixOffset(sp.X, y-r.Min.Y+sp.Y)
   103  			copy(dst.Pix[off0:][:r.Dx()*6], src.Pix[off1:])
   104  		}
   105  	default:
   106  		drawImage(dst, r, src, sp)
   107  	}
   108  }
   109  
   110  func drawRGB96f(dst *image_ext.RGB96f, r image.Rectangle, src image.Image, sp image.Point) {
   111  	switch src := src.(type) {
   112  	case *image_ext.RGB96f:
   113  		for y := r.Min.Y; y < r.Max.Y; y++ {
   114  			off0 := dst.PixOffset(r.Min.X, y)
   115  			off1 := src.PixOffset(sp.X, y-r.Min.Y+sp.Y)
   116  			copy(dst.Pix[off0:][:r.Dx()*12], src.Pix[off1:])
   117  		}
   118  	default:
   119  		drawImage(dst, r, src, sp)
   120  	}
   121  }
   122  
   123  func drawRGBA(dst *image.RGBA, r image.Rectangle, src image.Image, sp image.Point) {
   124  	switch src := src.(type) {
   125  	case *image.RGBA:
   126  		for y := r.Min.Y; y < r.Max.Y; y++ {
   127  			off0 := dst.PixOffset(r.Min.X, y)
   128  			off1 := src.PixOffset(sp.X, y-r.Min.Y+sp.Y)
   129  			copy(dst.Pix[off0:][:r.Dx()*4], src.Pix[off1:])
   130  		}
   131  	default:
   132  		drawImage(dst, r, src, sp)
   133  	}
   134  }
   135  
   136  func drawRGBA64(dst *image.RGBA64, r image.Rectangle, src image.Image, sp image.Point) {
   137  	switch src := src.(type) {
   138  	case *image.RGBA64:
   139  		for y := r.Min.Y; y < r.Max.Y; y++ {
   140  			off0 := dst.PixOffset(r.Min.X, y)
   141  			off1 := src.PixOffset(sp.X, y-r.Min.Y+sp.Y)
   142  			copy(dst.Pix[off0:][:r.Dx()*8], src.Pix[off1:])
   143  		}
   144  	default:
   145  		drawImage(dst, r, src, sp)
   146  	}
   147  }
   148  
   149  func drawRGBA128f(dst *image_ext.RGBA128f, r image.Rectangle, src image.Image, sp image.Point) {
   150  	switch src := src.(type) {
   151  	case *image_ext.RGBA128f:
   152  		for y := r.Min.Y; y < r.Max.Y; y++ {
   153  			off0 := dst.PixOffset(r.Min.X, y)
   154  			off1 := src.PixOffset(sp.X, y-r.Min.Y+sp.Y)
   155  			copy(dst.Pix[off0:][:r.Dx()*16], src.Pix[off1:])
   156  		}
   157  	default:
   158  		drawImage(dst, r, src, sp)
   159  	}
   160  }
   161  
   162  func drawYCbCr(dst *yCbCr, r image.Rectangle, src image.Image, sp image.Point) {
   163  	drawImage(dst, r, src, sp)
   164  }
   165  
   166  func drawImage(dst draw.Image, r image.Rectangle, src image.Image, sp image.Point) {
   167  	for y := r.Min.Y; y < r.Max.Y; y++ {
   168  		for x := r.Min.X; x < r.Max.X; x++ {
   169  			dst.Set(x, y, src.At(x-r.Min.X+sp.X, y-r.Min.Y+sp.Y))
   170  		}
   171  	}
   172  }