图像处理基本方法-go语言生产纯色BMP图片

图像处理基本方法-go语言生产纯色BMP图片

1、目的

我们有时需要产生各种各样的纯色图片,于是设计了这个简单的基本的图像处理小程序。

本文主要实现基本的BMP图片数据的生成过程,并保存为Windows可以识别的BMP文件。

本文是由go语言完成该功能,刚刚开始学习go语言,难免存在错误,但都是经过实战验证过的例子。

2、所需知识和材料

1)、windows电脑,安装vmware虚拟机,并安装ubuntu系统,ubuntu中安装了go语言编译环境。

2)、基本的go语言知识。

3)、BMP格式的知识。

除上面所列之外,还需基本的vim或gedit工具使用方法,基本的ubunut 下linux操作方法等。

3、go语言简介

Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。
罗伯特·格瑞史莫(Robert Griesemer),罗勃·派克(Rob Pike)及肯·汤普逊(Ken Thompson)于2007年9月开始设计Go,稍后Ian Lance Taylor、Russ Cox加入项目。Go是基于Inferno操作系统所开发的。Go于2009年11月正式宣布推出,成为开放源代码项目,并在Linux及Mac OS X平台上进行了实现,后来追加了Windows系统下的实现。在2016年,Go被软件评价公司TIOBE 选为“TIOBE 2016 年最佳语言”。

4、代码实现

//*******************************************************
// * file:testbmp.go
// * date:2021-05-07
// * version:1.0.0.1
// * author:jack8126
// * description: create bmp file
// *******************************************************/

package main

import (
	"encoding/binary"
	"fmt"
	"os"
	"strconv"
	"unsafe"
//	"bufio"
//	"io"
//	"io/ioutil" 
)

// bmp RGB
type BitmapRGB struct {
	Blue          uint8
	Green         uint8
	Red           uint8
}

// bmp info header
type BitmapInfoHeader struct {
	Size           uint32;
	Width          int32;
	Height         int32;
	Places         uint16;
	BitCount       uint16;
	Compression    uint32;
	SizeImage      uint32;
	XperlsPerMeter int32;
	YperlsPerMeter int32;
	ClsrUsed       uint32;
	ClrImportant   uint32;
}

// bmp file header
type  BitmapFileHeader struct{
    Type uint16; 
} 

// bmp file header2
type  BitmapFileHeader2 struct{

    Size uint32;
    Reserved1 uint16;
    Reserved2 uint16;
    OffBits uint32;
} 

func check(e error) {
	if e != nil {
		panic(e)
	}
}

// check file is existed
func checkFileIsExist(filename string) bool {
	var exist = true
	if _, err := os.Stat(filename); os.IsNotExist(err) {
		exist = false
	}
	return exist
}

func main() {

	//fmt.Println(argc)
	var index = 0;
	var fileName = "test2.bmp";
	var fileName2 = "test.bmp";
	var width = 1920;
	var height = 1080;
	var bit = 3;
	var red = 255;
	var green = 255;
	var blue = 255;
	var valueTmp = "12345";
	var strBlue = "255"
	var strGreen = "255"
	var strRed = "255"
	
	fmt.Println("main start, para info:");
	for idx, args := range os.Args{
		fmt.Println("para" + strconv.Itoa(idx) + ":", args);
		index = index + 1;

	}
	fmt.Println("index: " + strconv.Itoa(index))

	// check input commands
	if index < 8{
		fmt.Println("please input like this:");
		fmt.Println("./testbmp test.bmp 3 1920 1080 255 255 255");
		fmt.Println("test.bmp ------ bmp file name");
		fmt.Println("3        ------ 3 bytes RGB ");
		fmt.Println("1920     ------ bmp width ");
		fmt.Println("1080     ------ bmp height ");
		fmt.Println("255      ------ Blue ");
		fmt.Println("255      ------ Green ");
		fmt.Println("255      ------ Red ");
		return;
	}

	fileName2 = os.Args[1];
	valueTmp = os.Args[2]
	bit,err1 := strconv.Atoi(valueTmp)
	if(err1 != nil){
        fmt.Println("error1 happened ,exit")
        return  
    }
	width,err2 := strconv.Atoi(os.Args[3])
	if(err2 != nil){
        fmt.Println("error2 happened ,exit")
        return  
    }
    height,err3 := strconv.Atoi(os.Args[4])

	if(err3 != nil){
        fmt.Println("error3 happened ,exit")
        return  
    }
    blue,err4 := strconv.Atoi(os.Args[5])

	if(err4 != nil){
        fmt.Println("error4 happened ,exit")
        return  
    }
    green,err5 := strconv.Atoi(os.Args[6])

	if(err5 != nil){
        fmt.Println("error5 happened ,exit")
        return  
    }
    red,err6 := strconv.Atoi(os.Args[7])
	if(err6 != nil){
        fmt.Println("error6 happened ,exit")
        return 
    }

	strBlue = os.Args[5]
	strGreen = os.Args[6]
	strRed = os.Args[7]
	
	fmt.Println("fileName : " + fileName)
	fmt.Println("bit      : " + strconv.Itoa(bit))
	fmt.Println("width    : " + strconv.Itoa(width))
	fmt.Println("height   : " + strconv.Itoa(height))
	fmt.Println("blue     : " + strconv.Itoa(blue))
	fmt.Println("green    : " + strconv.Itoa(green))
	fmt.Println("red      : " + strconv.Itoa(red))
	fmt.Println("strBlue  : " + strBlue)
	fmt.Println("strGreen : " + strGreen)
	fmt.Println("strRed   : " + strRed)

	var err error;
	var file2 *os.File;

	/*
	var file *os.File;

	if checkFileIsExist(fileName){
		file, err = os.OpenFile(fileName, os.O_APPEND, 0666) //open file
		if err != nil {
			fmt.Println(err)
			return
		}
		fmt.Println("file is exist")
	} else {
		file, err = os.Create(fileName) //create file
		fmt.Println("file is not exist")
	}
	defer file.Close()

	//var headA, headB byte 
	//binary.Read(file, binary.LittleEndian, &headA)
	//binary.Read(file, binary.LittleEndian, &headB)
	binary.Read(file, binary.LittleEndian, &bmpFileHeader)

	fmt.Println(bmpFileHeader)
	
	//var size uint32
	//binary.Read(file, binary.LittleEndian, &size)
	binary.Read(file, binary.LittleEndian, &bmpFileHeader2)

	//var reservedA, reservedB uint16
	//binary.Read(file, binary.LittleEndian, &reservedA)
	//binary.Read(file, binary.LittleEndian, &reservedB)
	//binary.Read(file, binary.LittleEndian, &bmpFileHeader2.Reserved1)
	//binary.Read(file, binary.LittleEndian, &bmpFileHeader2.Reserved2)	

	//var offbits uint32
	//binary.Read(file, binary.LittleEndian, &offbits)
	//binary.Read(file, binary.LittleEndian, &bmpFileHeader2.OffBits)
	
	//fmt.Println(headA, headB, size, reservedA, reservedB, offbits)
	fmt.Println(bmpFileHeader2)
		
	
	infoHeader := new(BitmapInfoHeader)


	fmt.Println("infoHeader  size:", unsafe.Sizeof(infoHeader))
	fmt.Println("infoHeader2 size:", unsafe.Sizeof(infoHeader2))

	binary.Read(file, binary.LittleEndian, infoHeader)	
	binary.Read(file, binary.LittleEndian, &infoHeader2)
	fmt.Println(infoHeader)
	fmt.Println(infoHeader2)

	file.Sync();
	file.Close();
	//*/
	
	//*
	if checkFileIsExist(fileName2){
		file2, err = os.OpenFile(fileName2, os.O_APPEND, 0666) //open file
		if err != nil {
			fmt.Println(err)
			return
		}
		fmt.Println("file is exist")
	} else {
		file2, err = os.Create(fileName2) //create file
		fmt.Println("file is not exist")
	}
	defer file2.Close()
	//*/


	bmpFileHeader := BitmapFileHeader{};

	fmt.Println("bmpFileHeader  size:", unsafe.Sizeof(bmpFileHeader))

	bmpFileHeader2 := BitmapFileHeader2{};

	fmt.Println("bmpFileHeader2 size:", unsafe.Sizeof(bmpFileHeader2))

	infoHeader2 := BitmapInfoHeader{}


	bmpFileHeader.Type = 19778;

	bmpFileHeader2.Size = uint32(width) * uint32(height) * uint32(bit) + 54;//6220854;
	bmpFileHeader2.Reserved1 = 0;
	bmpFileHeader2.Reserved2 = 0;
	bmpFileHeader2.OffBits = 54;

	binary.Write(file2,binary.LittleEndian, bmpFileHeader) 

	binary.Write(file2,binary.LittleEndian, bmpFileHeader2) 




	
	infoHeader2.Size = uint32(40); // 

	fmt.Println("size    : " + strconv.Itoa(int(infoHeader2.Size)))
	
	infoHeader2.Width = int32(width);
	infoHeader2.Height = int32(height);
	infoHeader2.Places = 1;
	infoHeader2.BitCount = uint16(bit*8);
	infoHeader2.Compression = 0;
	infoHeader2.SizeImage = 0;
	infoHeader2.XperlsPerMeter = 3780;
	infoHeader2.YperlsPerMeter = 3780;
	infoHeader2.ClsrUsed = 0;
	infoHeader2.ClrImportant = 0;
	fmt.Println(infoHeader2)
	
	binary.Write(file2,binary.LittleEndian, infoHeader2) // write file



	//var d1 = []byte("123")
	//n2, err3 := file.Write(d1) // write file	
	//fmt.Println(n2);
	//binary.Write(file2,binary.LittleEndian, d1) 

	BitmapRGBData := BitmapRGB{uint8(blue),uint8(green),uint8(red)};
	fmt.Println(BitmapRGBData);
	
	for i := 0; i < height; i++ {
		for j := 0; j < width; j++ {
			binary.Write(file2,binary.LittleEndian, BitmapRGBData) 
		}
	}
        
	file2.Sync();


	file2.Close();
}


5、编译程序

编译命令如下:

go build testbmp.go

在这里插入图片描述

执行完上面命令,会产生testbmp的可执行文件。

后面执行程序时需要使用该文件。

6、执行程序

执行程序命令如下:

./testbmp test-go.bmp 3 1920 1080 255 255 0

在这里插入图片描述

编译执行命令如下:

go run testbmp.go test.bmp 3 1920 1080 255 255 0

在这里插入图片描述
从前面可以看出来go语言的特性,既可以编译执行,又可以作为脚本语言执行。
要修改分辨率和红绿蓝的值,可修改程序参数中的值。可以任意指定分辨率和色彩值。

7、参考资料

https://blog.csdn.net/n5/article/details/79142985

https://blog.csdn.net/jack8126/article/details/116331956

https://blog.csdn.net/jack8126/article/details/116466075

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值