Skip to content

Commit

Permalink
Add support for specifying alternate image encoding/compression metho…
Browse files Browse the repository at this point in the history
…d (creator).
  • Loading branch information
Gunnsteinn Hall authored and Gunnsteinn Hall committed Sep 5, 2017
1 parent 81967a2 commit 207d0ef
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 9 deletions.
41 changes: 41 additions & 0 deletions pdf/creator/creator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/boombuler/barcode/qr"

"github.com/unidoc/unidoc/common"
"github.com/unidoc/unidoc/pdf/core"
"github.com/unidoc/unidoc/pdf/model"
"github.com/unidoc/unidoc/pdf/model/fonts"
"github.com/unidoc/unidoc/pdf/model/textencoding"
Expand Down Expand Up @@ -73,6 +74,7 @@ func TestTemplate1(t *testing.T) {
return
}

// TestImage1 tests loading an image and adding to file at an absolute position.
func TestImage1(t *testing.T) {
creator := New()

Expand Down Expand Up @@ -104,6 +106,45 @@ func TestImage1(t *testing.T) {
}
}

// TestImageWithEncoder tests loading inserting an image with a specified encoder.
func TestImageWithEncoder(t *testing.T) {
creator := New()

imgData, err := ioutil.ReadFile(testImageFile1)
if err != nil {
t.Errorf("Fail: %v\n", err)
return
}

img, err := NewImageFromData(imgData)
if err != nil {
t.Errorf("Fail: %v\n", err)
return
}

// JPEG encoder (DCT) with quality factor 70.
encoder := core.NewDCTEncoder()
encoder.Quality = 70
encoder.Width = int(img.Width())
encoder.Height = int(img.Height())
img.SetEncoder(encoder)

img.SetPos(0, 100)
img.ScaleToWidth(1.0 * creator.Width())

err = creator.Draw(img)
if err != nil {
t.Errorf("Fail: %v\n", err)
return
}

err = creator.WriteToFile("/tmp/1_dct.pdf")
if err != nil {
t.Errorf("Fail: %v\n", err)
return
}
}

func TestShapes1(t *testing.T) {
creator := New()

Expand Down
43 changes: 34 additions & 9 deletions pdf/creator/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
// The Image type is used to draw an image onto PDF.
type Image struct {
xobj *model.XObjectImage
img *model.Image

// Rotation angle.
angle float64
Expand All @@ -46,20 +47,15 @@ type Image struct {

// Rotional origin. Default (0,0 - upper left corner of block).
rotOriginX, rotOriginY float64

// Encoder
encoder core.StreamEncoder
}

// NewImage create a new image from a unidoc image (model.Image).
func NewImage(img *model.Image) (*Image, error) {
image := &Image{}

// Create the XObject image.
ximg, err := model.NewXObjectImageFromImage(img, nil, core.NewFlateEncoder())
if err != nil {
common.Log.Error("Failed to create xobject image: %s", err)
return nil, err
}

image.xobj = ximg
image.img = img

// Image original size in points = pixel size.
image.origWidth = float64(img.Width)
Expand Down Expand Up @@ -113,6 +109,11 @@ func NewImageFromGoImage(goimg goimage.Image) (*Image, error) {
return NewImage(img)
}

// SetEncoder sets the encoding/compression mechanism for the image.
func (img *Image) SetEncoder(encoder core.StreamEncoder) {
img.encoder = encoder
}

// Height returns Image's document height.
func (img *Image) Height() float64 {
return img.height
Expand Down Expand Up @@ -141,8 +142,32 @@ func (img *Image) GetMargins() (float64, float64, float64, float64) {
return img.margins.left, img.margins.right, img.margins.top, img.margins.bottom
}

// makeXObject makes the encoded XObject Image that will be used in the PDF.
func (img *Image) makeXObject() error {
encoder := img.encoder
if encoder == nil {
// Default: Use flate encoder.
encoder = core.NewFlateEncoder()
}

// Create the XObject image.
ximg, err := model.NewXObjectImageFromImage(img.img, nil, encoder)
if err != nil {
common.Log.Error("Failed to create xobject image: %s", err)
return err
}

img.xobj = ximg
return nil
}

// GeneratePageBlocks generate the Page blocks. Draws the Image on a block, implementing the Drawable interface.
func (img *Image) GeneratePageBlocks(ctx DrawContext) ([]*Block, DrawContext, error) {
if img.xobj == nil {
// Build the XObject Image if not already prepared.
img.makeXObject()
}

blocks := []*Block{}
origCtx := ctx

Expand Down

0 comments on commit 207d0ef

Please sign in to comment.