github.com/amitbet/vnc2video@v0.0.0-20190616012314-9d50b9dab1d9/encoders/image-enc.go (about)

     1  package encoders
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"image"
     7  	"image/color"
     8  	"io"
     9  	"github.com/amitbet/vnc2video"
    10  )
    11  
    12  func encodePPMGeneric(w io.Writer, img image.Image) error {
    13  	maxvalue := 255
    14  	size := img.Bounds()
    15  	// write ppm header
    16  	_, err := fmt.Fprintf(w, "P6\n%d %d\n%d\n", size.Dx(), size.Dy(), maxvalue)
    17  	if err != nil {
    18  		return err
    19  	}
    20  
    21  	// write the bitmap
    22  	colModel := color.RGBAModel
    23  	row := make([]uint8, size.Dx()*3)
    24  	for y := size.Min.Y; y < size.Max.Y; y++ {
    25  		i := 0
    26  		for x := size.Min.X; x < size.Max.X; x++ {
    27  			color := colModel.Convert(img.At(x, y)).(color.RGBA)
    28  			row[i] = color.R
    29  			row[i+1] = color.G
    30  			row[i+2] = color.B
    31  			i += 3
    32  		}
    33  		if _, err := w.Write(row); err != nil {
    34  			return err
    35  		}
    36  	}
    37  	return nil
    38  }
    39  
    40  var convImage []uint8
    41  
    42  func encodePPMforRGBA(w io.Writer, img *image.RGBA) error {
    43  	maxvalue := 255
    44  	size := img.Bounds()
    45  	// write ppm header
    46  	_, err := fmt.Fprintf(w, "P6\n%d %d\n%d\n", size.Dx(), size.Dy(), maxvalue)
    47  	if err != nil {
    48  		return err
    49  	}
    50  
    51  	if convImage == nil {
    52  		convImage = make([]uint8, size.Dy()*size.Dx()*3)
    53  	}
    54  
    55  	rowCount := 0
    56  	for i := 0; i < len(img.Pix); i++ {
    57  		if (i % 4) != 3 {
    58  			convImage[rowCount] = img.Pix[i]
    59  			rowCount++
    60  		}
    61  	}
    62  
    63  	if _, err := w.Write(convImage); err != nil {
    64  		return err
    65  	}
    66  
    67  	return nil
    68  }
    69  
    70  func encodePPM(w io.Writer, img image.Image) error {
    71  	if img == nil {
    72  		return errors.New("nil image")
    73  	}
    74  	img1, isRGBImage := img.(*vnc2video.RGBImage)
    75  	img2, isRGBA := img.(*image.RGBA)
    76  	if isRGBImage {
    77  		return encodePPMforRGBImage(w, img1)
    78  	} else if isRGBA {
    79  		return encodePPMforRGBA(w, img2)
    80  	}
    81  	return encodePPMGeneric(w, img)
    82  }
    83  
    84  func encodePPMforRGBImage(w io.Writer, img *vnc2video.RGBImage) error {
    85  	maxvalue := 255
    86  	size := img.Bounds()
    87  	// write ppm header
    88  	_, err := fmt.Fprintf(w, "P6\n%d %d\n%d\n", size.Dx(), size.Dy(), maxvalue)
    89  	if err != nil {
    90  		return err
    91  	}
    92  
    93  	if _, err := w.Write(img.Pix); err != nil {
    94  		return err
    95  	}
    96  	return nil
    97  }
    98  
    99  type ImageEncoder interface {
   100  	Init(string)
   101  	Run()
   102  	Encode(image.Image)
   103  	Close()
   104  }