Jpeg.decode jpeg.encode yields unusable data

	r := strings.Split(p.UserToEdit.PhotoString64, ",")
	if len(r) == 2 {
		imageData = r[1]
	}

	buf := bytes.NewBufferString(imageData)
	reader := base64.NewDecoder(base64.StdEncoding, buf)

	decodedImage, err := jpeg.Decode(reader)

	buff1 := new(bytes.Buffer)
	err = jpeg.Encode(buff1, decodedImage, nil)
	if buff1 == buf{
		fmt.Println("equal")
	} else{
		fmt.Println("different")
	}

I am learning to encode/decode images for use in a web app. In the above code, p.UserToEdit.PhotoString64 is a base64 string which works in the browser with:
displayImage.style.backgroundImage = url({{.UserToEdit.PhotoString64}})`;

I am attempting to resize the image as a thumbnail using resize.Resize and am getting an unusable string, but I’ve written the above code to just get the decode/encode working. When I run the code, the buffers are very different. If I can get this figured out, I may be able to resize the image.

JPEG is lossy, so a re-encoding is unlikely to be equal to the original. Default quality is 75. Maybe you can get a match with quality = 100.

Also, you are comparing pointers to buffers, which also won’t be equal. Try comparing the base-64 encoded strings.

Thanks for your reply. I have looked at the buffers and they are different. The resulting decoded image does not display in the browser. It just results in an empty image and errors in the web inspector: invalid character. Also, looking at the base64 strings in web inspector, the original image data shows all printable characters starting with: data:image/png;base64,/9j/4AAQSkZJRgABAQEAS. whereas the encoded/decoded string is mostly non-printable characters starting with: data:image/png;base64,����\u0000�\u0000\u0008

Your string indicates the image is png, not jpeg.

Sorry about that, accidentally brought in a png file. I reran with a jpeg and the encoded image starts with:
`data:image/jpeg;base64,����\u0000�\u0000\u

I am writing the code to handle jpeg, png, and gif, but haven’t gotten any of them to work yet.

Are you sure you base64encoded correctly?

Well, I am starting with an encoded string which works in the browser. I am working on a longer snippet to show everything I’m doing. I’ll have it pretty soon…
Here is the javascript which is run after the user selects a file to upload, and it displays correctly.

        function processFile(imageInput) {

            const reader = new FileReader()
            reader.addEventListener("load", () => {
                uploaded_image = reader.result;
                let displayImage = document.querySelector("#display_image");
                displayImage.style.backgroundImage = `url(${uploaded_image})`;
                displayImage.value = uploaded_image;
                console.log(displayImage);
            });
            reader.readAsDataURL(imageInput.files[0]);
        }```
I then save it to a database.  I then retrieve that string and send it to the browser which displays it correctly.  I seem to be having an issue when I decode it, resize it, and encode it.  The result of that is a string which cannot be viewed in the browser.

Here is the code for my function:


func processImage(p *generalLedgerPage) {

	if len(p.UserToEdit.PhotoString64) == 0 {
		return
	}
	log.Println("processImage: ", p.UserToEdit.PhotoString64)
	// remove the header: i.e.: data:image/jpeg;base64, ...
	var imageData string
	r := strings.Split(p.UserToEdit.PhotoString64, ",")
	if len(r) == 2 {
		imageData = r[1]
	}

	fileType := ""
	buf := bytes.NewBufferString(imageData)
	reader := base64.NewDecoder(base64.StdEncoding, buf)
	decodedImage, err := jpeg.Decode(reader)
	if err != nil {
		log.Println("jpeg.Decode failed error: ", err)
		decodedImage, err = png.Decode(reader)
		if err != nil {
			log.Println("png.Decode failed error: ", err)
			decodedImage, err = gif.Decode(reader)
			if err != nil {
				log.Println("gif.Decode failed error: ", err)
			} else {
				fileType = "gif"
			}
		} else {
			fileType = "png"
		}
	} else {
		fileType = "jpg"
	}

	if err == nil {
		log.Println("decodedImage.Bounds(): ", decodedImage.Bounds())
	}

	//reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(p.UserToEdit.PhotoString64))
	// this will reset the position to start
	buf = bytes.NewBufferString(imageData)
	reader = base64.NewDecoder(base64.StdEncoding, buf)

	config, err := jpeg.DecodeConfig(reader)
	if err != nil {
		log.Println("error jpeg.DecodeConfig: ", err)
		config, err = png.DecodeConfig(reader)
		if err != nil {
			log.Println("error png.DecodeConfig: ", err)
			config, err = gif.DecodeConfig(reader)
			if err != nil {
				log.Println("error gif.DecodeConfig: ", err)
			}
		}
	}
	if config.Width > 0 {
		log.Println("jpeg.DecodeConfig success config: ", config)
		log.Println("Width:", config.Width, "Height:", config.Height)
	}


	buf1 := new(bytes.Buffer)
	var resizedImage image.Image
	if err == nil {
		resizedImage = resize.Resize(uint(100), 0, decodedImage, resize.Lanczos3)

		switch fileType {
		case "jpg":
			err = jpeg.Encode(buf1, resizedImage, nil)
			break
		case "png":
			err = png.Encode(buf1, resizedImage)
			break
		case "gif":
			err = gif.Encode(buf1, resizedImage, nil)
			break
		}

		if err != nil {
			log.Println("Encode error: ", err)
		}
	}

	if err == nil {
		p.UserToEdit.ThumbNailString64 = r[0] + "," + buf1.String()
		//p.UserToEdit.ThumbNailString64 = buff1.String()
		log.Println("p.UserToEdit.ThumbNailString64: ", p.UserToEdit.ThumbNailString64)
	}

}

The incoming file starts with:
`data:image/jpeg;base64,/9j/4AAQSkZJRgABAgEASABIAAD
and the rest of the file is all printable characters

the resulting file, p.UserToEdit.ThumbNailString64, starts with:
`data:image/jpeg;base64,ÿØÿۄaaaa
followed by many nonprintable characters, which basically crashes the browser window trying to process it.

This are random bytes, you have to base64 encode them.

1 Like

Thank you, I didn’t realize that the jpeg encoding had to then be base64 encoded. That works now.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.