signintech/gopdf

Support Image(s) From Readers

jenpet opened this issue · 3 comments

Hi there,

I've fiddled around with a lot of libs but this is so far the most promising one to me, so thanks for the effort you guys put into it. I'm currently facing an issue which either is caused by a misuse of the library within my code or by some missing functionality within the library itself.

Scenario:

I have base64 encoded images that I process within my application which are not available on disk as a binary file. The image format is a PNG and I need to add them into my generated PDFs. There are several approaches to this but the most obvious one does unfortunately not work for me.

Approach 1: using ImageFrom()

Decode the image and pass an image.Image variable into the lib's ImageFrom() function.

// setup foo
s := "<BASE64_ENCODED_IMG>"
r := base64.NewDecoder(base64.StdEncoding, strings.NewReader(s))
img, _, _ := image.Decode(r)
pdf.ImageFrom(img, 0,0, nil)

This results in a completely black box having the correct measurements but obviously not satisfying my actual need. Checking the ImageFrom() function puzzles me a bit since it enforces JPEG encoding independent of the actual image input.

    // ...
    go func() {
		bw := bufio.NewWriter(w)
		err := jpeg.Encode(bw, img, nil)
		bw.Flush()
		if err != nil {
			w.CloseWithError(err)
		} else {
			w.Close()
		}
	}()
    // ...

Approach 2: write to and again read from disk using Image()

This possibility is unfortunately not a real option since I do not want to invest into housekeeping of images which are only temporarily written to the disk, re-read into the memory and then get deleted again. Nevertheless, it actually works since it utilizes different image processing logic.

Possible Mitigation(s)

  • I completely missed a clean way to get base64 encoded PNG-typed images into a PDF page using existing functionality
  • Enhance the ImageFrom() function to take image types into account and not try to force them to be JPEGs. This might either cause an uncomfortable signature change to also pass in the type of the image which can be received by image.Decode() or some kind of an internal "re-calculation" of the type.
  • My personal favorite as of now: provide a ImageFromReader(imgReader io.Reader, x float64, y float64, rect *Rect) error function which basically does the same as ImageFrom() but without the reader-writer piping.

Let me guys know what you think about it or give me a little push in the right direction in case I'm somehow lost.

Regards & thanks

ixuer commented

In fact, there is no restriction to use .jpeg format images. I used go-chart to generate the chart, then converted it to bytes, and then used ImageHolderByBytes().
If the image content cannot be read, consider whether it is because image.Decode() has finished reading the data stream.

Hey @ixuer thanks for your reply. Will check that during the next days and maybe come back with a snippet that either works or doesn't :-D Appreciate your answer!

@oneplus1000 can you close this issue if it has been resolved? It seems to have been resolved.