【Gin框架入门到精通系列14】Gin框架中的国际化与本地化

GIN框架介绍以及使用 李文周的博客 阅读详情

📚 原创系列: “Gin框架入门到精通系列”

🔄 转载说明: 本文最初发布于"Gopher部落"微信公众号,经原作者授权转载。

🔗 关注原创: 欢迎扫描文末二维码,关注"Gopher部落"微信公众号获取第一手Gin框架技术文章。

📑 Gin框架学习系列导航

本文是【Gin框架入门到精通系列14】的第14篇 - Gin框架中的国际化与本地化

高级特性篇
  1. Gin框架中的国际化与本地化👈 当前位置
  2. Gin框架中的WebSocket实时通信
  3. Gin框架的优雅关闭与热重启
  4. Gin框架的请求限流与熔断

🔍 查看完整系列文章

📖 文章导读

1.1 本节知识点概述

本文是Gin框架入门到精通系列的第十四篇文章,主要介绍如何在Gin应用中实现国际化(i18n)与本地化(l10n)。通过本文的学习,你将了解到:

  • 国际化与本地化的基本概念和区别
  • Go语言中常用的国际化库及其用法
  • 在Gin框架中实现多语言支持的方法
  • 基于用户偏好的语言自动检测与切换
  • 处理不同时区、日期格式和数字格式的策略
  • 本地化资源(图片、图标等)的管理方法
  • 国际化应用的测试与验证技巧

1.2 学习目标说明

完成本节学习后,你将能够:

  • 理解并区分国际化(i18n)和本地化(l10n)的概念
  • 在Gin应用中实现完整的多语言支持
  • 根据用户浏览器设置或用户选择自动切换语言
  • 正确处理不同地区的日期、时间、数字和货币格式
  • 设计支持多语言的数据库模型和API响应
  • 构建面向全球用户的Web应用,提供良好的本地化体验
  • 对国际化应用进行有效的测试和质量保证

1.3 预备知识要求

学习本教程需要以下预备知识:

  • Go语言基础知识
  • Gin框架的基本概念(路由、中间件等)
  • HTML模板的基本用法
  • RESTful API设计的基本理解
  • 已完成前十三篇教程的学习,特别是中间件、模板和请求处理相关内容

二、理论讲解

2.1 国际化与本地化基础概念

2.1.1 国际化与本地化的区别

在构建全球化的Web应用时,国际化(Internationalization,简称i18n)和本地化(Localization,简称l10n)是两个密切相关但不同的概念:

  • 国际化(i18n):是指设计和开发应用程序时,使其能够适应不同语言和地区的过程,而无需进行工程上的修改。简单来说,国际化是创建一个"可本地化"的应用框架,使应用程序的核心代码与特定语言和文化无关。

  • 本地化(l10n):是指使应用程序适应特定语言、文化区域或市场的过程。本地化不仅包括翻译用户界面文本,还包括适应当地的日期格式、货币单位、数字格式、排序规则等。

注:i18n和l10n的缩写形式分别来源于单词的首尾字母与中间字母数量,如internationalization的首字母i和末字母n之间有18个字母,因此缩写为i18n。

国际化是本地化的前提和基础,一个设计良好的国际化系统可以大大简化本地化的过程。

2.1.2 国际化的关键要素

成功的国际化策略通常需要考虑以下几个关键要素:

  1. 文本外部化:将用户界面中的所有文本从代码中分离出来,存储在外部资源文件中,便于翻译和管理。

  2. Unicode支持:使用Unicode字符集来处理文本,确保应用程序可以正确显示和处理各种语言的字符。

  3. 复数形式处理:不同语言对复数的处理方式不同,例如英语有单数和复数两种形式,而阿拉伯语有六种复数形式。

  4. 日期和时间格式:不同地区使用不同的日期和时间格式,如美国使用MM/DD/YYYY,而大多数欧洲国家使用DD/MM/YYYY。

  5. 数字和货币格式:不同地区使用不同的数字格式(如小数点、千位分隔符)和货币符号。

  6. 方向性支持:某些语言如阿拉伯语和希伯来语是从右向左(RTL)阅读的,需要特殊的界面设计。

  7. 排序和比较:不同语言有不同的字母排序规则和字符比较方法。

2.1.3 本地化的关键要素

本地化过程通常包括以下几个方面:

  1. 文本翻译:将用户界面中的文本翻译成目标语言,包括菜单、按钮、提示信息等。

  2. 文化适应:调整应用程序以适应目标文化的习惯和偏好,如颜色选择、图标设计等。

  3. 内容适应:根据当地法律、习俗和文化敏感性调整内容,有时甚至需要重新创建内容。

  4. 技术适应:解决不同地区可能遇到的技术问题,如网络连接速度、设备类型分布等。

  5. 法律合规:确保应用程序符合目标市场的法律法规,如隐私政策、数据保护要求等。

2.2 Go语言国际化方案

2.2.1 常用国际化库

Go语言生态系统中有几个流行的国际化库:

  1. go-i18n:一个功能完整的国际化库,支持复数形式、模板化消息和JSON/YAML格式的翻译文件。

    import "github.com/nicksnyder/go-i18n/v2/i18n"
    
  2. i18next-go:Go语言版本的i18next,支持丰富的翻译功能和插件系统。

    import "github.com/i18next-go/i18next"
    
  3. go-locale:用于检测系统区域设置的库,可以与其他i18n库结合使用。

    import "github.com/Xuanwo/go-locale"
    
  4. gotext:实现了gettext国际化标准的Go库,适合从其他使用gettext的项目迁移。

    import "github.com/leonelquinteros/gotext"
    

在本教程中,我们将主要使用go-i18n库,因为它功能全面、文档完善,并且与Gin框架集成较为简单。

2.2.2 翻译文件格式与组织

国际化应用通常使用以下几种格式组织翻译文件:

  1. JSON格式:简单易读,被许多前端框架支持。

    {
         
         
      "greeting": "你好,世界!",
      "welcome_message": "欢迎访问我们的网站。"
    }
    
  2. YAML格式:比JSON更易读,特别是对于大型翻译文件。

    greeting: 你好,世界!
    welcome_message: 欢迎访问我们的网站。
    
  3. PO/MO格式:gettext使用的标准格式,提供更多元数据和上下文信息。

    msgid "greeting"
    msgstr "你好,世界!"
    
    msgid "welcome_message"
    msgstr "欢迎访问我们的网站。"
    

翻译文件的组织方式通常有两种:

  1. 按语言组织:为每种语言创建一个文件,包含所有翻译。

    locales/
    ├── en.json
    ├── zh.json
    ├── ja.json
    └── de.json
    
  2. 按功能和语言组织:先按功能模块分目录,再按语言分文件。

    locales/
    ├── common/
    │   ├── en.json
    │   └── zh.json
    ├── user/
    │   ├── en.json
    │   └── zh.json
    └── product/
        ├── en.json
        └── zh.json
    

在大型项目中,第二种组织方式更有优势,便于模块化开发和维护。

2.2.3 语言检测与切换

有几种常见的方法来检测用户的首选语言并允许语言切换:

  1. 从HTTP请求头检测:浏览器通过Accept-Language头部发送用户的语言偏好。

    func detectLanguage(c *gin.Context) string {
         
         
        acceptLanguage := c.GetHeader("Accept-Language")
        // 解析Accept-Language并返回最合适的语言
    }
    
  2. 从URL参数检测:通过URL参数或路径段指定语言。

    https://example.com/en/products
    https://example.com/products?lang=en
    
  3. 从用户设置检测:已登录用户可能在系统中设置了语言偏好。

  4. 从Cookie检测:先前的语言选择可以存储在Cookie中。

    func detectLanguage(c *gin.Context) string {
         
         
        lang, err := c.Cookie("language")
        if err == nil && lang != "" {
         
         
            return lang
        }
        // 回退到其他检测方法
    }
    

最佳实践是结合多种方法,按照优先级依次检测:

  1. URL参数或路径(最高优先级)
  2. 用户设置(需登录)
  3. Cookie
  4. Accept-Language头部
  5. 默认语言(最低优先级)

2.3 模板中的国际化

2.3.1 HTML模板国际化

在Gin框架中,我们可以通过以下几种方式在HTML模板中实现国际化:

  1. 使用自定义模板函数:在模板中注册一个翻译函数。

    // 在Go代码中注册模板函数
    r.SetFuncMap(template.FuncMap{
         
         
        "t": func(messageID string, args ...interface{
         
         }) string {
         
         
            // 使用i18n库翻译消息
            return i18n.T(messageID, args...)
        },
    })
    
    <!-- 在HTML模板中使用 -->
    <h1>{
        
        { t "greeting" }}</h1>
    <p>{
        
        { t "welcome_message" }}</p>
    
  2. 使用模板变量:在渲染模板前准备翻译好的消息。

    // 在Go代码中准备翻译
    translations := map[string]string{
         
         
        "greeting":        i18n.T("greeting"),
        "welcome_message": i18n.T("welcome_message"),
    }
    c.HTML(http.StatusOK, "index.html", gin.H{
         
         
        "translations": translations,
    })
    
    <!-- 在HTML模板中使用 -->
    <h1>{
        
        { .translations.greeting }}</h1>
    <p>{
        
        { .translations.welcome_message }}</p>
    
  3. 使用占位符:对于包含变量的消息。

    // 在模板函数中支持变量替换
    "t": func(messageID string, args ...interface{
         
         }) string {
         
         
        // 使用i18n库翻译消息,支持参数替换
        return i18n.T(messageID, args...)
    },
    
    <!-- 在HTML模板中使用 -->
    <p>{
        
        { t "welcome_name" .user.Name }}</p>
    

    对应的翻译文件:

    {
         
         
      "welcome_name": "欢迎,{
         
         {.}}!"
    }
    
2.3.2 复数形式和上下文支持

处理复数形式是国际化的一个重要方面:

  1. go-i18n复数支持:使用Plural方法或特殊语法。

    {
         
         
      "items_count": {
         
         
        "one": "{
         
         {.Count}}个项目",
        "other": "{
         
         {.Count}}个项目"
      }
    }
    
    // 在Go代码中使用
    message := i18n.Plural("items_count", count, map[string]interface{
         
         }{
         
         
        "Count": count,
    })
    
    <!-- 在HTML模板中使用 -->
    <p>{
        
        { tp "items_count" .count }}</p>
    
  2. 上下文支持:同一词汇在不同上下文中可能有不同翻译。

    {
         
         
      "save_as_file": "保存为文件",
      "save_as_draft": "保存为草稿"
    }
    

    使用时指定完整的消息ID,或支持上下文参数的翻译函数。

2.4 API响应国际化

2.4.1 REST API国际化策略

对于RESTful API的国际化,通常有以下几种策略:

  1. 基于请求头的语言选择:客户端通过Accept-Language头部指定语言。

    GET /api/products HTTP/1.1
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
    
  2. 基于查询参数的语言选择:客户端通过URL参数指定语言。

    GET /api/products?lang=zh-CN
    
  3. 内容协商:使用HTTP内容协商机制,客户端请求特定语言版本的资源。

    GET /api/products HTTP/1.1
    Accept: application/json; charset=utf-8
    Accept-Language: zh-CN
    

    服务器响应:

    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    Content-Language: zh-CN
    
  4. 分离内容和元数据:将内容和翻译分开返回,由客户端合并。

    {
         
         
      "products": [
        {
         
         
          "id": 1,
          "name_key": "product_1_name",
          "description_key": "product_1_description"
        }
      ],
      "translations": {
         
         
        "zh-CN": {
         
         
          "product_1_name": "产品1",
          "product_1_description": "这是产品1的描述"
        }
      }
    }
    
2.4.2 错误消息国际化

API错误消息的国际化特别重要,可以通过以下方式实现:

  1. 使用消息ID和翻译文本:

    {
         
         
      "error": {
         
         
        "code": "invalid_input",
        "message": "输入数据无效",
        "details": [
          {
         
         
            "field": "email",
            "code": "email_format",
            "message": "电子邮件格式不正确"
          }
        ]
      }
    }
    
  2. 仅返回消息ID,客户端负责翻译:

    {
         
         
      "error": {
         
         
        "code": "invalid_input",
        "message_id": "error.invalid_input",
        "details": [
          {
         
         
            "field": "email",
            "code": "email_format",
            "message_id": "error.email_format"
          }
        ]
      }
    }
    
  3. 同时返回默认文本和消息ID:

    {
         
         
      "error": {
         
         
        "code": "invalid_input",
        "message": "Invalid input data",
        "message_id": "error.invalid_input",
        "details": [
          {
         
         
            "field": "email",
            "code": "email_format",
            "message": "Invalid email format",
            "message_id": "error.email_format"
          }
        ]
      }
    }
    

2.5 本地化最佳实践

2.5.1 区域特定内容

除了文本翻译外,应用程序还需要处理区域特定的内容:

  1. 日期和时间格式:使用区域设置格式化日期和时间。

    import "golang.org/x/text/date"
    
    // 根据区域设置格式化日期
    formatter := date.NewPatternFormatter("2006-01-02")
    formattedDate := formatter.Format(time.Now(), language.English)
    
  2. 数字和货币格式:不同地区使用不同的小数点、千位分隔符和货币符号。

    import "golang.org/x/text/number"
    import "golang.org/x/text/currency"
    
    // 格式化数字
    formatter := number.NewDecimal(2, number.WithFormatOptions(number.WithGroup(',')))
    formattedNumber := formatter.Format(12345.67)
    
    // 格式化货币
    currencyFormatter := currency.Symbol(currency.USD.Amount(12345.67))
    formattedCurrency := currencyFormatter.Format(language.English)
    
  3. 地址格式:不同国家的地址格式差异很大。

  4. 名称格式:姓名的顺序和格式在不同文化中有所不同(如姓在前还是名在前)。

2.5.2 图像和资源本地化

应用程序中的图像和资源也可能需要本地化:

  1. 图标和图像:某些图标和图像在不同文化背景下可能有不同含义或需要适应。

  2. 布局调整:从左到右(LTR)和从右到左(RTL)语言需要不同的布局。

    /* RTL支持的CSS示例 */
    html[dir="rtl"] .sidebar {
         
         
      float: right;
    }
    html[dir="ltr"] .sidebar {
         
         
      float: left;
    }
    
  3. 资源路径:根据语言或区域组织资源路径。

    /static/images/en/logo.png
    /static/images/zh/logo.png
    
2.5.3 数据库内容国际化

对于需要在数据库中存储多语言内容的应用程序,有几种常见的方法:

  1. 独立表方法:为每种语言创建独立的内容表。

    CREATE TABLE products (
      id INT PRIMARY KEY,
      /* 语言无关字段 */
    );
    
    CREATE TABLE product_translations (
      product_id INT REFERENCES products(id),
      language_code VARCHAR(10),
      name VARCHAR(100),
      description TEXT,
      PRIMARY KEY (product_id, language_code)
    );
    
  2. JSON字段方法:使用JSON字段存储多语言内容(适用于支持JSON的数据库)。

    CREATE TABLE products (
      id INT PRIMARY KEY,
      name_translations JSONB,
      description_translations JSONB
    );
    

    示例数据:

    {
         
         
      "name_translations": {
         
         
        "en": "Product 1",
        "zh": "产品1",
        "ja": "製品1"
      }
    }
    
  3. 预先连接方法:在查询时连接翻译表。

    SELECT p.id, pt.name, pt.description
    FROM products p
    JOIN product_translations pt ON p.id = pt.product_id
    WHERE pt.language_code = 'zh';
    

选择哪种方法取决于应用程序的需求、数据库类型和查询模式。

三、代码实践

在本节中,我们将通过一系列实际的代码示例,展示如何在Gin框架中实现国际化和本地化功能。我们将使用go-i18n库作为主要的国际化工具,并结合Gin的特性来构建一个多语言支持的Web应用。

3.1 基础国际化设置

让我们从一个基础的国际化设置开始,为我们的Gin应用添加多语言支持。

3.1.1 项目初始化

首先,我们需要创建一个新的Gin项目并安装必要的依赖:

// 初始化模块
go mod init i18n-demo

// 安装依赖
go get -u github.com/gin-gonic/gin
go get -u github.com/nicksnyder/go-i18n/v2/i18n
go get -u golang.org/x/text/language
3.1.2 创建翻译文件

接下来,我们需要创建翻译文件。在项目根目录下创建一个locales文件夹,并添加以下翻译文件:

locales/en.json:

{
   
   
  "welcome": {
   
   
    "message": "Welcome to our website!",
    "description": "Welcome message displayed on the home page"
  },
  "greeting": {
   
   
    "message": "Hello, {
   
   {.Name}}!",
    "description": "Greeting with user's name"
  },
  "items_count": {
   
   
    "one": "You have {
   
   {.Count}} item.",
    "other": "You have {
   
   {.Count}} items.",
    "description": "Number of items the user has"
  },
  "nav": {
   
   
    "home": {
   
   
      "message": "Home",
      "description": "Navigation link to home page"
    },
    "about": {
   
   
      "message": "About",
      "description": "Navigation link to about page"
    },
    "contact": {
   
   
      "message": "Contact",
      "description": "Navigation link to contact page"
    }
  }
}

locales/zh.json:

{
   
   
  "welcome": {
   
   
    "message": "欢迎访问我们的网站!",
    "description": "首页显示的欢迎信息"
  },
  "greeting": {
   
   
    "message": "你好,{
   
   {.Name}}!",
    "description": "带有用户名的问候语"
  },
  "items_count": {
   
   
    "one": "你有 {
   
   {.Count}} 个物品。",
    "other": "你有 {
   
   {.Count}} 个物品。",
    "description": "用户拥有的物品数量"
  },
  "nav": {
   
   
    "home": {
   
   
      "message": "首页",
      "description": "导航链接到首页"
    },
    "about": {
   
   
      "message": "关于我们",
      "description": "导航链接到关于页面"
    },
    "contact": {
   
   
      "message": "联系我们",
      "description": "导航链接到联系页面"
    }
  }
}

locales/ja.json:

{
   
   
  "welcome": {
   
   
    "message": "ウェブサイトへようこそ!",
    "description": "ホームページに表示される歓迎メッセージ"
  },
  "greeting": {
   
   
    "message": "こんにちは、{
   
   {.Name}}さん!",
    "description": "ユーザー名を含む挨拶"
  },
  "items_count": {
   
   
    "one": "{
   
   {.Count}}個のアイテムがあります。",
    "other": "{
   
   {.Count}}個のアイテムがあります。",
    "description": "ユーザーが持っているアイテムの数"
  },
  "nav": {
   
   
    "home": {
   
   
      "message": "ホーム",
      "description": "ホームページへのナビゲーションリンク"
    },
    "about": {
   
   
      "message": "概要",
      "description": "概要ページへのナビゲーションリンク"
    },
    "contact": {
   
   
      "message": "お問い合わせ",
      "description": "お問い合わせページへのナビゲーションリンク"
    }
  }
}
3.1.3 创建i18n包装器

现在,我们将创建一个i18n包装器,用于初始化国际化功能并提供翻译方法:

// i18n/i18n.go
package i18n

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"github.com/nicksnyder/go-i18n/v2/i18n"
	"golang.org/x/text/language"
)

// I18n 是我们的国际化管理器
type I18n struct {
   
   
	bundle       *i18n.Bundle
	localizer    *i18n.Localizer
	defaultLang  string
	fallbackLang string
}

// New 创建一个新的I18n实例
func New(defaultLang, fallbackLang, localesPath string) (*I18n, error) {
   
   
	// 创建一个新的bundle,以defaultLang作为默认语言
	bundle := i18n.NewBundle(language.Make(defaultLang))
	
	// 设置JSON解码器
	bundle.RegisterUnmarshalFunc("json", json.Unmarshal)

	// 加载翻译文件
	err := loadTranslationFiles(bundle, localesPath)
	if err != nil {
   
   
		return nil, err
	}

	// 创建本地化器
	localizer := i18n.NewLocalizer(bundle, defaultLang, fallbackLang)

	return &I18n{
   
   
		bundle:       bundle,
		localizer:    localizer,
		defaultLang:  defaultLang,
		fallbackLang: fallbackLang,
	}, nil
}

// loadTranslationFiles 加载指定目录下的所有翻译文件
func loadTranslationFiles(bundle *i18n.Bundle, path string) error {
   
   
	files, err := os.ReadDir(path)
	if err != nil {
   
   
		return err
	}

	for _, file := range files {
   
   
		if file.IsDir() {
   
   
			continue
		}

		// 只处理JSON文件
		if !strings.HasSuffix(file.Name(), ".json") {
   
   
			continue
		}

		// 加载翻译文件
		_, err := bundle.LoadMessageFile(filepath.Join(path, file.Name()))
		if err != nil {
   
   
			return err
		}
	}

	return nil
}

// SetLanguage 设置当前语言
func (i *I18n) SetLanguage(langs ...string) {
   
   
	i.localizer = i18n.NewLocalizer(i.bundle, lang
golang——Gin框架及路由介绍 gin框架中采用的路由库是基于httprouter做的支持Restful风格的API,意思是"表面层状态转化",是一个互联网应用程序的API设计理念:URL定位资源。可以创建路由组,为了管理相同的URL。import ("net/http"//将应用切换到“发布模式”以提升性能//创建路由//默认使用了两个中间件Logger(),Recovery()})})//路由组1})})//路由组2})})//监听端口,默认绑定端口8080。 阅读详情

相关推荐

【Gin框架入门到精通系列】全系列导航手册

本文是Gin框架入门到精通系列的导航手册,系统梳理了从入门到精通的25篇学习资源。包含基础入门、中间件、高级功能、测试部署和架构实战等全方位内容,为您提供清晰的Gin框架学习路径。

GopherTribe的博客 3396

Cursor Blog:AI Agent在IDE中的可调试沙盒实践

AI Agent 是当前大模型应用落地的核心范式,其本质是将LLM作为推理引擎,通过Tool调用实现任务分解与执行闭环。理解Agent需从基础原理出发:它依赖明确的意图识别、标准化的工具接口、上下文感知的规划能力,以及本地化、低延迟的调试体验。相比Serverless框架(如Harness),IDE-native Agent方案更强调开发即部署、环境即上下文、调试即交互。Cursor Blog正是这一理念的工程化实现——它不是内容发布平台,而是首个深度集成于代码编辑器的Agent运行时控制台,支持自定义To

weixin_34406086的博客 352

海量数据 / Vastbase 深度研究笔记 v3.1

v3.1 重点修订:在 v3.0 审慎版基础上,新增“2026 新变量”章节,纳入 7 亿级定增、HTAP / 多模态时序数据库、G100 V3.0 Build 8 的 3CM+2DN 高可用补强、pgvector / V100 / AI 多模叙事,以及集成服务基因与标准软件 ARR 的拉扯。核心关注点是:Vastbase 能否把 openGauss 生态红利、数据库产品矩阵和行业交付能力,转化为可持续、可复购、低边际成本的标准软件收入。海量不是没有业务基本盘,也不是马上失血致死;客户越多,服务债越大。

喝醉酒的小白 557

STM32结合FFT与窗函数优化,实现高精度正弦信号提取

本文详细介绍了如何在STM32嵌入式平台上结合FFT算法与窗函数优化技术,实现高精度正弦信号提取。通过分析频谱泄漏原理,对比汉宁窗、汉明窗等窗函数特性,并提供实际代码示例和幅值补偿方法,有效解决了工业检测中信号精度不足的问题。

v5w6x的博客 221

某程token参数逆向分析

作者声明:文章仅供学习交流与参考!严禁用于任何商业与非法用途!否则由此产生的一切后果均与作者无关!如有侵权,请联系作者本人进行删除!

weixin_73499887的博客 2882

【图像压缩】超先验模型 《VARIATIONAL IMAGE COMPRESSION WITH A SCALE HYPERPRIOR》

绪论 2015年,第一个端到端图像编码方案被提出。基于深度学习的端到端图像压缩主要分为两类,一类是基于RNN的方法,一类是基于CNN的方法。本文对基于CNN的方法

hahalidaxin的专栏 1万+

国内用户稳定开通ChatGPT Plus会员的完整实操指南

ChatGPT作为当前最先进的AI对话模型,其技术原理基于Transformer架构和大规模语言预训练。通过深度学习技术,ChatGPT能够理解自然语言并生成高质量回复,在代码生成、文档分析等场景具有重要技术价值。对于需要高频使用的开发者而言,ChatGPT Plus会员提供了优先访问权和GPT-4模型支持等核心功能。在实际应用场景中,国内用户常面临支付限制和区域封锁等挑战。本文针对这些痛点,重点解析如何通过可靠的支付渠道和账号安全策略,实现稳定的会员开通方案,帮助用户突破技术使用壁垒,充分发挥AI助手在开

weixin_29042035的博客 954

Vector CANoe VT2516A实战:从硬件连接到CAPL脚本的完整配置指南

本文详细介绍了Vector CANoe VT2516A板卡从硬件连接到CAPL脚本编写的完整配置指南。涵盖硬件接线原则、VT System配置避坑技巧、系统变量创建规范、可视化Panel设计、CAPL脚本调试及典型故障排查案例,帮助工程师快速掌握VT2516A板卡的应用实践,提升汽车电子测试效率。

weixin_30608503的博客 254

【32】OpenCV——图像含义关系?RGGB , BGGR , GRBG , GBRG呢?raw8,raw10,raw12,raw14呢? YUV422; RAW16呢?YCbYCr/RG_GB;

‌如前所述,定义原始数据的位深精度。‌* ‌一种压缩色彩编码方式,通过色度抽样(亮度Y全分辨率,色度U/V半分辨率)减少数据量,常用于视频传输。‌* ‌可能指每个像素分量占16位存储(如高位填充的RAW10/12/14),或未明确量化的高精度原始数据。‌ ‌分类‌核心定义‌关联性及典型应用传感器原始色彩排列(RGGB/BGGR等)决定RAW数据的色彩分布规则RAW位深每个分量的数据精度(8/10/12/14位)影响动态范围和存储空间‌YUV422。

程序员,他们想的是什么?他们想的永远都是技术,他们崇尚的也永远都是技术。 794

【PointNet++】使用Open3D对分割后的结果可视化

PointNet++中的局部分割网络预测后是没有可视化文件的,所以需要自己通过编写Open3D或者PCL点云算法去可视化,在本人经过查找翻阅修改后,实现了网络输出点云分割后结果的可视化。已实现推测单个点云,并可视化。

纵马踏花向自由 2453

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

上一篇: 【Gin框架入门到精通系列13】Gin框架中的认证与授权
下一篇: 【Gin框架入门到精通系列15】Gin框架中的WebSocket实时通信
Gopher部落
博客等级 码龄2年 784粉丝 92原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gopher部落

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值