go image.DecodeConfig 和image.Decode 不能同时使用吗

问题场景:在同时使用go image.DecodeConfig 和image.Decode获取图片信息时,报错提示:

无法读取图像配置 image: unknown format

package mainimport ("fmt""github.com/golang/freetype""image""image/draw""image/jpeg""os""time"
)func main() {// 打开原始图片file, err := os.Open("004.jpeg")if err != nil {panic(err)}defer file.Close()// 解码图片img, _, err := image.Decode(file)if err != nil {panic(err)}// 创建一个画布bounds := img.Bounds()canvas := image.NewRGBA(bounds)// 打开图像文件fileInfo, err := os.Stat("004.jpeg")if err != nil {fmt.Sprintf("无法获取文件信息:%v", err)}fmt.Println("文件名:",fileInfo.Name())// 读取图像信息//image.Config{ Width: image.DecodeConfig()}config, _, err := image.DecodeConfig(file)if err != nil {fmt.Println("无法读取图像配置", err)}width := config.Widthheight := config.Heightfmt.Println("图片宽度为:", width)fmt.Println("图片高度为:", height)//s,err:=file.Stat()//fmt.Println(file.Name(),s.Size(),s.Sys(),s.Mode(),s.ModTime())// 绘制原始图片到画布上draw.Draw(canvas, bounds, img, image.Point{}, draw.Src)// 添加文字fontBytes, err := os.ReadFile("../ttf/kaiti.TTF") //解析中文//fontBytes, err := os.ReadFile("../ttf/luxisr.ttf") //不解析中文if err != nil {panic(err)}font, err := freetype.ParseFont(fontBytes)if err != nil {panic(err)}context := freetype.NewContext()context.SetDPI(72)context.SetFont(font)context.SetFontSize(25)context.SetClip(bounds)context.SetDst(canvas)context.SetSrc(image.Opaque)pt := freetype.Pt(0, 5+int(context.PointToFixed(24)>>6))context.DrawString("来源公众号:【码农编程进阶笔记】", pt)// 保存处理后的图片filename := fmt.Sprintf("output_%d.jpg", time.Now().Unix())output, err := os.Create(filename)if err != nil {panic(err)}defer output.Close()// 编码保存到文件jpeg.Encode(output, canvas, nil)
}

原因:

试图从同一个io.reader(文件)读取两次。

解决:
	//在image.DecodeConfig 和image.Decode两者之间,添加该行问题解决file.Seek(0, io.SeekStart)

 完整代码:

package mainimport ("fmt""github.com/golang/freetype""image""image/draw""image/jpeg""io""os""time"
)func main() {// 打开原始图片file, err := os.Open("004.jpeg")if err != nil {panic(err)}defer file.Close()// 解码图片img, _, err := image.Decode(file)if err != nil {panic(err)}// 创建一个画布bounds := img.Bounds()canvas := image.NewRGBA(bounds)// 打开图像文件fileInfo, err := os.Stat("004.jpeg")if err != nil {fmt.Sprintf("无法获取文件信息:%v", err)}fmt.Println("文件名:",fileInfo.Name())//添加该行问题解决file.Seek(0, io.SeekStart)// 读取图像信息//image.Config{ Width: image.DecodeConfig()}config, _, err := image.DecodeConfig(file)if err != nil {fmt.Println("无法读取图像配置", err)}width := config.Widthheight := config.Heightfmt.Println("图片宽度为:", width)fmt.Println("图片高度为:", height)//s,err:=file.Stat()//fmt.Println(file.Name(),s.Size(),s.Sys(),s.Mode(),s.ModTime())// 绘制原始图片到画布上draw.Draw(canvas, bounds, img, image.Point{}, draw.Src)// 添加文字fontBytes, err := os.ReadFile("../ttf/kaiti.TTF") //解析中文//fontBytes, err := os.ReadFile("../ttf/luxisr.ttf") //不解析中文if err != nil {panic(err)}font, err := freetype.ParseFont(fontBytes)if err != nil {panic(err)}context := freetype.NewContext()context.SetDPI(72)context.SetFont(font)context.SetFontSize(25)context.SetClip(bounds)context.SetDst(canvas)context.SetSrc(image.Opaque)pt := freetype.Pt(0, 5+int(context.PointToFixed(24)>>6))context.DrawString("来源公众号:【码农编程进阶笔记】", pt)// 保存处理后的图片filename := fmt.Sprintf("output_%d.jpg", time.Now().Unix())output, err := os.Create(filename)if err != nil {panic(err)}defer output.Close()// 编码保存到文件jpeg.Encode(output, canvas, nil)
}

方法一:(代码简洁,亲测可用

解释:大概意思,

将下一个读取或写入文件的偏移量设置为偏移量,根据以下内容进行解释:0表示相对于文件原点,1表示相对于当前偏移量,2表示相对于终点。它返回新的偏移量和一个错误(如果有的话)。

在使用O_APPEND打开的文件上,未指定Seek的行为。

如果f是一个目录,则Seek的行为因操作而异

系统您可以在类Unix操作系统上查找目录的开头,但不能在Windows上查找。

最终,还是再次读取文件。


// Seek sets the offset for the next Read or Write on file to offset, interpreted
// according to whence: 0 means relative to the origin of the file, 1 means
// relative to the current offset, and 2 means relative to the end.
// It returns the new offset and an error, if any.
// The behavior of Seek on a file opened with O_APPEND is not specified.
//
// If f is a directory, the behavior of Seek varies by operating
// system; you can seek to the beginning of the directory on Unix-like
// operating systems, but not on Windows.
func (f *File) Seek(offset int64, whence int) (ret int64, err error) {if err := f.checkValid("seek"); err != nil {return 0, err}r, e := f.seek(offset, whence)if e == nil && f.dirinfo != nil && r != 0 {e = syscall.EISDIR}if e != nil {return 0, f.wrapErr("seek", e)}return r, nil
}

方法二:(有点麻烦)

您试图从同一个io.reader(文件)读取两次。

image.DecodeConfig(file)

第二次在

image.Decode(file)

第二次尝试从同一个io.reader读取时,将得到EOF
当Read在成功阅读n〉0字节后遇到错误或文件结束条件时,它返回读取的字节数。它可以返回(non-nil)来自同一调用的错误或返回错误这种一般情况的一个示例是,在输入流的末尾返回非零字节数的Reader可以返回err == 0(并且n == 0)。EOF或err == nil。下一次读取应返回0,EOF。
在这里关于它https://golang.org/pkg/io/#Reader
一些快速和简单的你可以做的是打开文件两次

file, err := os.Open("test2.png")
if err != nil {fmt.Println("0 ", err)return
}
imageInConfig, _, err := image.DecodeConfig(file)
if err != nil {fmt.Println("1 ", err)return
}
file2, err := os.Open("test2.png")
if err != nil {fmt.Println("3 ", err)return
}
imageIn, _, err := image.Decode(file2)
if err != nil {fmt.Println("4 ", err)return
}

或者,您可以尝试多次阅读同一个文件。How to read multiple times from same io.Reader

 参考:Go语言 image.decode在解码.png文件时返回错误 _大数据知识库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/609247.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MYSQL的SWITCH语句和循环语句

1. 请解释MySQL中的CASE语句和IF语句的区别。 MySQL中的CASE语句和IF语句都可以用于条件判断,但它们的使用方式和语法有所不同。 CASE语句:CASE语句是一种更灵活的条件判断结构,它可以处理多个条件和结果。CASE语句的基本语法如下&#xff…

Python入门知识点分享——(十三)内置函数

先向大家致歉,这几天忙于单片机的复习和考试,耽误了Python知识的分享。今天在回顾的时候发现数据计算还有些遗漏的部分,基本上都属于Python的内置函数,就一并补充在这篇文章中。 Python内置函数是在Python解释器中已经预定义的函…

Qt/QML编程学习之心得:一个蓝牙音乐播放器的实现(30)

蓝牙bluetooth作为一种短距离的通信方式应用也是越来越广,比如很多智能家居、蓝牙遥控器、蓝牙音箱、蓝牙耳机、蓝牙手表等,手机的蓝牙功能更是可以和各种设备进行互联,甚至可以连接到车机上去配合wifi提供投屏、音乐等。那么如何在中控IVI上使用Qt来实现一个蓝牙音乐播放器…

Kotlin函数式接口

函数式接口 接口只有一个抽象方法的接口,称为 函数式接口 functional interface,也叫做 Single Abstract Method(SAM) interface。 注:函数式接口,只有一个抽象方法,但可以有多个非抽象方法。 一、Kotlin Kotlin支持…

用 MATLAB 产生单位抽样序列、单位阶跃序列、矩形序列、正弦序列和复指数序列

%% 单位抽样(脉冲)序列(冲激函数) % 参数设置 n -10:10; % 定义时间范围 delta (n 0); % 生成单位抽样序列% 绘图 figure; stem(n, delta); title(单位抽样序列); xlabel(n); ylabel(delta[n]);%% 单位阶跃序列 % 参数设置 n …

axios 后端不配和添加api

export function returnBaseUrl(proxyUrl, url) {// console.log(process.env, "process.env3333");let returnBaseUrl "";if (process.env.NODE_ENV "production") {// // test 环境// if (process.env.VUE_APP_ENV "test") {// …

C# 学习笔记-基础与变量

《Csharp 8.0 and .NET Core 3.0 – Modern Cross-Platform Development 4th Edition》第二章 基础与变量 不涉及高级和晦涩的主题,例如 ref 局部变量重新分配和值类型的引用语义。 基础 用反射获取类型数量: using System.Linq; using System.Refl…

Swagger 教程:从零开始学习Swagger

Swagger 是一个开源的 API 设计和文档工具,可以帮助全栈工程师更快、更简单地设计、构建、文档化和测试 RESTful API。本篇文章将为全栈工程师介绍 Swagger 的基础知识和使用方法,以及如何使用 Swagger 设计、文档化和测试 RESTful API。 一、Swagger 简…

SLF4J Spring Boot日志框架

JAVA日志框架 JAVA有好多优秀的日志框架,比如log4j、log4j2、logback、JUL(java.util.logging)、JCL(JAVA Common Logging)等等,logback是后起之秀,是Spring Boot默认日志框架。 今天文章的目…

oracle19c容器数据库rman备份特性-----性能优化(三)

目录 冗余备份片 1.备份的时候指定 2.rman配置中设定 归档备份(将备份集保留) 二级备份(将备份文件保留) 1.备份闪回恢复区的恢复文件 2.备份所有恢复文件 recovery catalog database 1.創建recovery catalog 2.创建VPC…

zabbix-proxy代理安装及其他监控方式

zabbix-proxy代理安装及其他监控方式 安装zabbix-proxyserver端配置zabbix-proxy配置被监控的agent安装中问题解决监控网络设备JMX和IPMI监控方式 zabbix-proxy的安装,至少需要准备三台机器,一台安装服务端,一台安装agent端,这里就…

《网络是怎样连接的》2.3节图表(自用)

图4.1:TCP拆分数据与ACK号 图4.2:连接阶段与通信阶段ACK号与序号的交互过程 首先,客户端在连接时需要计算出与从客户端到服务器方向通信相关的序号初始值,并将这个值发送给服务器(①)。 接下来&#xff0c…

基于SpringBoot的企业OA管理系统

文章目录 项目介绍主要功能截图:部分代码展示设计总结项目获取方式🍅 作者主页:超级无敌暴龙战士塔塔开 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获取源码联系🍅 项目介绍 基于SpringBoot的企业OA管理系统,java项…

【C++PCL】点云处理LCCP分割

作者:迅卓科技 简介:本人从事过多项点云项目,并且负责的项目均已得到好评! 公众号:迅卓科技,一个可以让您可以学习点云的好地方 本专栏特色:根据经验和大家分享每个参数的调试规范,解决大家因为参数的问题而产生的苦恼。 目录 1.原理介绍 2.代码效果 3.源码展示

HTTP协议九种请求方法的异同

HTTP(Hypertext Transfer Protocol)定义了多种请求方法(也称为HTTP方法或动作),用于指定客户端对服务器执行的操作。以下是HTTP协议中常见的九种请求方法: 1. **GET:** - 用于请求指定的资源…

在k8s集群中部署多nginx-ingress

关于ingress的介绍,前面已经详细讲过了,参考ingress-nginx详解和部署方案。本案例ingress的部署使用deploymentLB的方式。 参考链接: 多个ingress部署 文章目录 1. 下载ingress的文件2. 文件资源分析3. 部署ingress3.1 部署第一套ingress3.1…

C# 反射的乌云,MethodInfo的Json序列化参数入参问题

文章目录 前言直接运行MethodInfo运行结果 Json解决ParamterInfo实例化运行结果无法实例化问题部分参数的问题 Json反序列化 经过长达一天的研究,我终于完全的解决的了实战思路方法测试用例运行测试运行结果 代码总结总结 前言 我上篇文章已经基本解决了反射的基本…

众和策略:沪指跌0.91%险守2900点,半导体、金融等板块走低

8日早盘,两市股指低开低走,沪指一度失守2900点,深成指、创业板指跌约1%,科创50指数创前史新低。 到午间收盘,沪指跌0.91%报2902.4点,深成指跌1.17%,创业板指跌0.99%,科创50指数跌超…

python每日学12:面向对象的编程

背景:最近有些时间,打算把python每日学的计划继续执行起来。由于不知道从何入手,就暂定从学习《python学习手册》开始,这本书也是python领域的一本权威著作,各方面都写的非常详细,读起来很有帮助&#xff0…

pythonPandas四:数据操作与转换

当涉及到数据操作和转换时,Pandas提供了许多有用的功能。以下是一些示例说明: 1.数据选择和操作: import pandas as pd# 创建一个示例DataFrame data {Name: [Alice, Bob, Charlie],Age: [25, 30, 35],City: [New York, London, Paris]} d…