package core import ( "encoding/binary" "fmt" "io" "os" ) // BMPFileHeader represents the bitmap file header structure. type BMPFileHeader struct { FileType [2]byte FileSize uint32 Reserved1 uint16 Reserved2 uint16 DataOffset uint32 } // BMPInfoHeader represents the bitmap info header structure. type BMPInfoHeader struct { Size uint32 Width int32 Height int32 Planes uint16 BitsPerPixel uint16 Compression uint32 SizeImage uint32 XPelsPerMeter int32 YPelsPerMeter int32 ColorsUsed uint32 ColorsImportant uint32 } func ReadBmpImage(filePath string) (error, int32, int32) { file, err := os.Open(filePath) if err != nil { fmt.Printf("=== Failed to open file: %v\n", err) return err, 0, 0 } defer file.Close() // Read the file header. var fileHeader BMPFileHeader if err := binary.Read(file, binary.LittleEndian, &fileHeader); err != nil { fmt.Printf("=== Failed to Read file: %v\n", err) return err, 0, 0 } // Check if it's a valid BMP file by verifying the file type. if string(fileHeader.FileType[:]) != "BM" { return fmt.Errorf("not a valid BMP file: file type is %q, expected \"BM\"", string(fileHeader.FileType[:])), 0, 0 } // Read the info header. var infoHeader BMPInfoHeader if err := binary.Read(file, binary.LittleEndian, &infoHeader); err != nil { fmt.Printf("=== Failed to Read file: %v\n", err) return err, 0, 0 } // 自顶向下 BMP 的高度为负值,取绝对值避免影响后续解析 return err, absInt32(infoHeader.Width), absInt32(infoHeader.Height) //fmt.Printf("=== File size: %d bytes\n", fileHeader.FileSize) //fmt.Printf("=== Image dimensions: %dx%d\n", ) //fmt.Printf("=== Bits per pixel: %d\n", infoHeader.BitsPerPixel) // At this point, you would typically read the pixel data into a slice, // taking into account any padding required for alignment and the specific // pixel format (e.g., RGB, RGBA, indexed color). This part is omitted here. // You may also need to skip over a possible color palette if present. // The size of the palette can be inferred from the number of colors used and // the bits per pixel value. // For simplicity, we'll just read the rest of the file as raw bytes. //data, err := ioutil.ReadAll(file) //if err != nil { // panic(err) //} //fmt.Printf("=== Read %d bytes of pixel data.\n", len(data)) } // absInt32 返回 int32 的绝对值 func absInt32(v int32) int32 { if v < 0 { return -v } return v } // ReadPsdImage 读取PSD/PSB格式的图片信息(两者共享相同的8BPS文件头) func ReadPsdImage(filePath string) (err error, width int, height int) { file, err := os.Open(filePath) if err != nil { fmt.Printf("=== Failed to open file: %v\n", err) return err, 0, 0 } defer file.Close() var header [26]byte if _, err := io.ReadFull(file, header[:]); err != nil { fmt.Printf("=== Failed to read PSD/PSB header: %v\n", err) return err, 0, 0 } if string(header[0:4]) != "8BPS" { return fmt.Errorf("not a valid PSD/PSB file: magic %q, expected \"8BPS\"", string(header[0:4])), 0, 0 } version := binary.BigEndian.Uint16(header[4:6]) if version != 1 && version != 2 { return fmt.Errorf("unsupported PSD/PSB version: %d", version), 0, 0 } height = int(binary.BigEndian.Uint32(header[14:18])) width = int(binary.BigEndian.Uint32(header[18:22])) return nil, width, height }