Breaking changes: changed the function signature for 2 exported functions

- Change
    `func (f *File) AddPictureFromBytes(sheet, cell, name, extension string, file []byte, opts *GraphicOptions) error`
    to
    `func (f *File) AddPictureFromBytes(sheet, cell string, pic *Picture) error`
- Change
    `func (f *File) GetPicture(sheet, cell string) (string, []byte, error)`
    to
    `func (f *File) GetPictures(sheet, cell string) ([]Picture, error)`

Co-authored-by: huangsk <645636204@qq.com>
This commit is contained in:
xuri 2023-03-19 20:23:33 +08:00
parent 7631fd08e1
commit 478b528af1
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7
5 changed files with 91 additions and 78 deletions

View File

@ -52,9 +52,8 @@ func TestConcurrency(t *testing.T) {
},
))
// Concurrency get cell picture
name, raw, err := f.GetPicture("Sheet1", "A1")
assert.Equal(t, "", name)
assert.Nil(t, raw)
pics, err := f.GetPictures("Sheet1", "A1")
assert.Len(t, pics, 0)
assert.NoError(t, err)
// Concurrency iterate rows
rows, err := f.Rows("Sheet1")

View File

@ -1558,7 +1558,7 @@ func prepareTestBook1() (*File, error) {
return nil, err
}
err = f.AddPictureFromBytes("Sheet1", "Q1", "Excel Logo", ".jpg", file, nil)
err = f.AddPictureFromBytes("Sheet1", "Q1", &Picture{Extension: ".jpg", File: file, Format: &GraphicOptions{AltText: "Excel Logo"}})
if err != nil {
return nil, err
}

View File

@ -145,19 +145,18 @@ func parseGraphicOptions(opts *GraphicOptions) *GraphicOptions {
//
// The optional parameter "ScaleY" specifies the vertical scale of images,
// the default value of that is 1.0 which presents 100%.
func (f *File) AddPicture(sheet, cell, picture string, opts *GraphicOptions) error {
func (f *File) AddPicture(sheet, cell, name string, opts *GraphicOptions) error {
var err error
// Check picture exists first.
if _, err = os.Stat(picture); os.IsNotExist(err) {
if _, err = os.Stat(name); os.IsNotExist(err) {
return err
}
ext, ok := supportedImageTypes[path.Ext(picture)]
ext, ok := supportedImageTypes[path.Ext(name)]
if !ok {
return ErrImgExt
}
file, _ := os.ReadFile(filepath.Clean(picture))
_, name := filepath.Split(picture)
return f.AddPictureFromBytes(sheet, cell, name, ext, file, opts)
file, _ := os.ReadFile(filepath.Clean(name))
return f.AddPictureFromBytes(sheet, cell, &Picture{Extension: ext, File: file, Format: opts})
}
// AddPictureFromBytes provides the method to add picture in a sheet by given
@ -188,7 +187,11 @@ func (f *File) AddPicture(sheet, cell, picture string, opts *GraphicOptions) err
// fmt.Println(err)
// return
// }
// if err := f.AddPictureFromBytes("Sheet1", "A2", "Excel Logo", ".jpg", file, nil); err != nil {
// if err := f.AddPictureFromBytes("Sheet1", "A2", &excelize.Picture{
// Extension: ".jpg",
// File: file,
// Format: &excelize.GraphicOptions{AltText: "Excel Logo"},
// }); err != nil {
// fmt.Println(err)
// return
// }
@ -196,15 +199,15 @@ func (f *File) AddPicture(sheet, cell, picture string, opts *GraphicOptions) err
// fmt.Println(err)
// }
// }
func (f *File) AddPictureFromBytes(sheet, cell, name, extension string, file []byte, opts *GraphicOptions) error {
func (f *File) AddPictureFromBytes(sheet, cell string, pic *Picture) error {
var drawingHyperlinkRID int
var hyperlinkType string
ext, ok := supportedImageTypes[extension]
ext, ok := supportedImageTypes[pic.Extension]
if !ok {
return ErrImgExt
}
options := parseGraphicOptions(opts)
img, _, err := image.DecodeConfig(bytes.NewReader(file))
options := parseGraphicOptions(pic.Format)
img, _, err := image.DecodeConfig(bytes.NewReader(pic.File))
if err != nil {
return err
}
@ -219,7 +222,7 @@ func (f *File) AddPictureFromBytes(sheet, cell, name, extension string, file []b
drawingXML := "xl/drawings/drawing" + strconv.Itoa(drawingID) + ".xml"
drawingID, drawingXML = f.prepareDrawing(ws, drawingID, sheet, drawingXML)
drawingRels := "xl/drawings/_rels/drawing" + strconv.Itoa(drawingID) + ".xml.rels"
mediaStr := ".." + strings.TrimPrefix(f.addMedia(file, ext), "xl")
mediaStr := ".." + strings.TrimPrefix(f.addMedia(pic.File, ext), "xl")
drawingRID := f.addRels(drawingRels, SourceRelationshipImage, mediaStr, hyperlinkType)
// Add picture with hyperlink.
if options.Hyperlink != "" && options.HyperlinkType != "" {
@ -229,7 +232,7 @@ func (f *File) AddPictureFromBytes(sheet, cell, name, extension string, file []b
drawingHyperlinkRID = f.addRels(drawingRels, SourceRelationshipHyperLink, options.Hyperlink, hyperlinkType)
}
ws.Unlock()
err = f.addDrawingPicture(sheet, drawingXML, cell, name, ext, drawingRID, drawingHyperlinkRID, img, options)
err = f.addDrawingPicture(sheet, drawingXML, cell, ext, drawingRID, drawingHyperlinkRID, img, options)
if err != nil {
return err
}
@ -319,7 +322,7 @@ func (f *File) countDrawings() int {
// addDrawingPicture provides a function to add picture by given sheet,
// drawingXML, cell, file name, width, height relationship index and format
// sets.
func (f *File) addDrawingPicture(sheet, drawingXML, cell, file, ext string, rID, hyperlinkRID int, img image.Config, opts *GraphicOptions) error {
func (f *File) addDrawingPicture(sheet, drawingXML, cell, ext string, rID, hyperlinkRID int, img image.Config, opts *GraphicOptions) error {
col, row, err := CellNameToCoordinates(cell)
if err != nil {
return err
@ -358,7 +361,7 @@ func (f *File) addDrawingPicture(sheet, drawingXML, cell, file, ext string, rID,
pic := xlsxPic{}
pic.NvPicPr.CNvPicPr.PicLocks.NoChangeAspect = opts.LockAspectRatio
pic.NvPicPr.CNvPr.ID = cNvPrID
pic.NvPicPr.CNvPr.Descr = file
pic.NvPicPr.CNvPr.Descr = opts.AltText
pic.NvPicPr.CNvPr.Name = "Picture " + strconv.Itoa(cNvPrID)
if hyperlinkRID != 0 {
pic.NvPicPr.CNvPr.HlinkClick = &xlsxHlinkClick{
@ -556,10 +559,10 @@ func (f *File) getSheetRelationshipsTargetByID(sheet, rID string) string {
return ""
}
// GetPicture provides a function to get picture base name and raw content
// GetPictures provides a function to get picture meta info and raw content
// embed in spreadsheet by given worksheet and cell name. This function
// returns the file name in spreadsheet and file contents as []byte data
// types. This function is concurrency safe. For example:
// returns the image contents as []byte data types. This function is
// concurrency safe. For example:
//
// f, err := excelize.OpenFile("Book1.xlsx")
// if err != nil {
@ -571,27 +574,29 @@ func (f *File) getSheetRelationshipsTargetByID(sheet, rID string) string {
// fmt.Println(err)
// }
// }()
// file, raw, err := f.GetPicture("Sheet1", "A2")
// pics, err := f.GetPictures("Sheet1", "A2")
// if err != nil {
// fmt.Println(err)
// return
// }
// if err := os.WriteFile(file, raw, 0644); err != nil {
// for idx, pic := range pics {
// name := fmt.Sprintf("image%d%s", idx+1, pic.Extension)
// if err := os.WriteFile(name, pic.File, 0644); err != nil {
// fmt.Println(err)
// }
func (f *File) GetPicture(sheet, cell string) (string, []byte, error) {
// }
func (f *File) GetPictures(sheet, cell string) ([]Picture, error) {
col, row, err := CellNameToCoordinates(cell)
if err != nil {
return "", nil, err
return nil, err
}
col--
row--
ws, err := f.workSheetReader(sheet)
if err != nil {
return "", nil, err
return nil, err
}
if ws.Drawing == nil {
return "", nil, err
return nil, err
}
target := f.getSheetRelationshipsTargetByID(sheet, ws.Drawing.RID)
drawingXML := strings.ReplaceAll(target, "..", "xl")
@ -601,7 +606,7 @@ func (f *File) GetPicture(sheet, cell string) (string, []byte, error) {
return f.getPicture(row, col, drawingXML, drawingRelationships)
}
// DeletePicture provides a function to delete charts in spreadsheet by given
// DeletePicture provides a function to delete all pictures in a cell by given
// worksheet name and cell reference. Note that the image file won't be deleted
// from the document currently.
func (f *File) DeletePicture(sheet, cell string) error {
@ -624,7 +629,7 @@ func (f *File) DeletePicture(sheet, cell string) error {
// getPicture provides a function to get picture base name and raw content
// embed in spreadsheet by given coordinates and drawing relationships.
func (f *File) getPicture(row, col int, drawingXML, drawingRelationships string) (ret string, buf []byte, err error) {
func (f *File) getPicture(row, col int, drawingXML, drawingRelationships string) (pics []Picture, err error) {
var (
wsDr *xlsxWsDr
ok bool
@ -636,7 +641,7 @@ func (f *File) getPicture(row, col int, drawingXML, drawingRelationships string)
if wsDr, _, err = f.drawingParser(drawingXML); err != nil {
return
}
if ret, buf = f.getPictureFromWsDr(row, col, drawingRelationships, wsDr); len(buf) > 0 {
if pics = f.getPicturesFromWsDr(row, col, drawingRelationships, wsDr); len(pics) > 0 {
return
}
deWsDr = new(decodeWsDr)
@ -655,9 +660,11 @@ func (f *File) getPicture(row, col int, drawingXML, drawingRelationships string)
if deTwoCellAnchor.From.Col == col && deTwoCellAnchor.From.Row == row {
drawRel = f.getDrawingRelationships(drawingRelationships, deTwoCellAnchor.Pic.BlipFill.Blip.Embed)
if _, ok = supportedImageTypes[filepath.Ext(drawRel.Target)]; ok {
ret = filepath.Base(drawRel.Target)
pic := Picture{Extension: filepath.Ext(drawRel.Target), Format: &GraphicOptions{}}
if buffer, _ := f.Pkg.Load(strings.ReplaceAll(drawRel.Target, "..", "xl")); buffer != nil {
buf = buffer.([]byte)
pic.File = buffer.([]byte)
pic.Format.AltText = deTwoCellAnchor.Pic.NvPicPr.CNvPr.Descr
pics = append(pics, pic)
}
return
}
@ -667,10 +674,10 @@ func (f *File) getPicture(row, col int, drawingXML, drawingRelationships string)
return
}
// getPictureFromWsDr provides a function to get picture base name and raw
// getPicturesFromWsDr provides a function to get picture base name and raw
// content in worksheet drawing by given coordinates and drawing
// relationships.
func (f *File) getPictureFromWsDr(row, col int, drawingRelationships string, wsDr *xlsxWsDr) (ret string, buf []byte) {
func (f *File) getPicturesFromWsDr(row, col int, drawingRelationships string, wsDr *xlsxWsDr) (pics []Picture) {
var (
ok bool
anchor *xdrCellAnchor
@ -684,11 +691,12 @@ func (f *File) getPictureFromWsDr(row, col int, drawingRelationships string, wsD
if drawRel = f.getDrawingRelationships(drawingRelationships,
anchor.Pic.BlipFill.Blip.Embed); drawRel != nil {
if _, ok = supportedImageTypes[filepath.Ext(drawRel.Target)]; ok {
ret = filepath.Base(drawRel.Target)
pic := Picture{Extension: filepath.Ext(drawRel.Target), Format: &GraphicOptions{}}
if buffer, _ := f.Pkg.Load(strings.ReplaceAll(drawRel.Target, "..", "xl")); buffer != nil {
buf = buffer.([]byte)
pic.File = buffer.([]byte)
pic.Format.AltText = anchor.Pic.NvPicPr.CNvPr.Descr
pics = append(pics, pic)
}
return
}
}
}

View File

@ -26,7 +26,7 @@ func BenchmarkAddPictureFromBytes(b *testing.B) {
}
b.ResetTimer()
for i := 1; i <= b.N; i++ {
if err := f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", i), "excel", ".png", imgFile, nil); err != nil {
if err := f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", i), &Picture{Extension: ".png", File: imgFile, Format: &GraphicOptions{AltText: "Excel"}}); err != nil {
b.Error(err)
}
}
@ -58,9 +58,9 @@ func TestAddPicture(t *testing.T) {
assert.NoError(t, f.AddPicture("AddPicture", "A1", filepath.Join("test", "images", "excel.jpg"), &GraphicOptions{AutoFit: true}))
// Test add picture to worksheet from bytes
assert.NoError(t, f.AddPictureFromBytes("Sheet1", "Q1", "Excel Logo", ".png", file, nil))
assert.NoError(t, f.AddPictureFromBytes("Sheet1", "Q1", &Picture{Extension: ".png", File: file, Format: &GraphicOptions{AltText: "Excel Logo"}}))
// Test add picture to worksheet from bytes with illegal cell reference
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "A", "Excel Logo", ".png", file, nil), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "A", &Picture{Extension: ".png", File: file, Format: &GraphicOptions{AltText: "Excel Logo"}}), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
assert.NoError(t, f.AddPicture("Sheet1", "Q8", filepath.Join("test", "images", "excel.gif"), nil))
assert.NoError(t, f.AddPicture("Sheet1", "Q15", filepath.Join("test", "images", "excel.jpg"), nil))
@ -75,7 +75,7 @@ func TestAddPicture(t *testing.T) {
f = NewFile()
f.ContentTypes = nil
f.Pkg.Store(defaultXMLPathContentTypes, MacintoshCyrillicCharset)
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "Q1", "Excel Logo", ".png", file, nil), "XML syntax error on line 1: invalid UTF-8")
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "Q1", &Picture{Extension: ".png", File: file, Format: &GraphicOptions{AltText: "Excel Logo"}}), "XML syntax error on line 1: invalid UTF-8")
// Test add picture with invalid sheet name
assert.EqualError(t, f.AddPicture("Sheet:1", "A1", filepath.Join("test", "images", "excel.jpg"), nil), ErrSheetNameInvalid.Error())
@ -90,10 +90,11 @@ func TestAddPictureErrors(t *testing.T) {
// Test add picture to worksheet with unsupported file type
assert.EqualError(t, f.AddPicture("Sheet1", "G21", filepath.Join("test", "Book1.xlsx"), nil), ErrImgExt.Error())
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "G21", "Excel Logo", "jpg", make([]byte, 1), nil), ErrImgExt.Error())
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "G21", &Picture{Extension: "jpg", File: make([]byte, 1), Format: &GraphicOptions{AltText: "Excel Logo"}}), ErrImgExt.Error())
// Test add picture to worksheet with invalid file data
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "G21", "Excel Logo", ".jpg", make([]byte, 1), nil), image.ErrFormat.Error())
assert.EqualError(t, f.AddPictureFromBytes("Sheet1", "G21", &Picture{Extension: ".jpg", File: make([]byte, 1), Format: &GraphicOptions{AltText: "Excel Logo"}}), image.ErrFormat.Error())
// Test add picture with custom image decoder and encoder
decode := func(r io.Reader) (image.Image, error) { return nil, nil }
@ -115,41 +116,39 @@ func TestAddPictureErrors(t *testing.T) {
func TestGetPicture(t *testing.T) {
f := NewFile()
assert.NoError(t, f.AddPicture("Sheet1", "A1", filepath.Join("test", "images", "excel.png"), nil))
name, content, err := f.GetPicture("Sheet1", "A1")
pics, err := f.GetPictures("Sheet1", "A1")
assert.NoError(t, err)
assert.Equal(t, 13233, len(content))
assert.Equal(t, "image1.png", name)
assert.Len(t, pics[0].File, 13233)
assert.Empty(t, pics[0].Format.AltText)
f, err = prepareTestBook1()
if !assert.NoError(t, err) {
t.FailNow()
}
file, raw, err := f.GetPicture("Sheet1", "F21")
pics, err = f.GetPictures("Sheet1", "F21")
assert.NoError(t, err)
if !assert.NotEmpty(t, filepath.Join("test", file)) || !assert.NotEmpty(t, raw) ||
!assert.NoError(t, os.WriteFile(filepath.Join("test", file), raw, 0o644)) {
if !assert.NotEmpty(t, filepath.Join("test", fmt.Sprintf("image1%s", pics[0].Extension))) || !assert.NotEmpty(t, pics[0].File) ||
!assert.NoError(t, os.WriteFile(filepath.Join("test", fmt.Sprintf("image1%s", pics[0].Extension)), pics[0].File, 0o644)) {
t.FailNow()
}
// Try to get picture from a worksheet with illegal cell reference
_, _, err = f.GetPicture("Sheet1", "A")
_, err = f.GetPictures("Sheet1", "A")
assert.EqualError(t, err, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
// Try to get picture from a worksheet that doesn't contain any images
file, raw, err = f.GetPicture("Sheet3", "I9")
pics, err = f.GetPictures("Sheet3", "I9")
assert.EqualError(t, err, "sheet Sheet3 does not exist")
assert.Empty(t, file)
assert.Empty(t, raw)
assert.Len(t, pics, 0)
// Try to get picture from a cell that doesn't contain an image
file, raw, err = f.GetPicture("Sheet2", "A2")
pics, err = f.GetPictures("Sheet2", "A2")
assert.NoError(t, err)
assert.Empty(t, file)
assert.Empty(t, raw)
assert.Len(t, pics, 0)
// Test get picture with invalid sheet name
_, _, err = f.GetPicture("Sheet:1", "A2")
_, err = f.GetPictures("Sheet:1", "A2")
assert.EqualError(t, err, ErrSheetNameInvalid.Error())
f.getDrawingRelationships("xl/worksheets/_rels/sheet1.xml.rels", "rId8")
@ -163,36 +162,34 @@ func TestGetPicture(t *testing.T) {
f, err = OpenFile(filepath.Join("test", "TestGetPicture.xlsx"))
assert.NoError(t, err)
file, raw, err = f.GetPicture("Sheet1", "F21")
pics, err = f.GetPictures("Sheet1", "F21")
assert.NoError(t, err)
if !assert.NotEmpty(t, filepath.Join("test", file)) || !assert.NotEmpty(t, raw) ||
!assert.NoError(t, os.WriteFile(filepath.Join("test", file), raw, 0o644)) {
if !assert.NotEmpty(t, filepath.Join("test", fmt.Sprintf("image1%s", pics[0].Extension))) || !assert.NotEmpty(t, pics[0].File) ||
!assert.NoError(t, os.WriteFile(filepath.Join("test", fmt.Sprintf("image1%s", pics[0].Extension)), pics[0].File, 0o644)) {
t.FailNow()
}
// Try to get picture from a local storage file that doesn't contain an image
file, raw, err = f.GetPicture("Sheet1", "F22")
pics, err = f.GetPictures("Sheet1", "F22")
assert.NoError(t, err)
assert.Empty(t, file)
assert.Empty(t, raw)
assert.Len(t, pics, 0)
assert.NoError(t, f.Close())
// Test get picture from none drawing worksheet
f = NewFile()
file, raw, err = f.GetPicture("Sheet1", "F22")
pics, err = f.GetPictures("Sheet1", "F22")
assert.NoError(t, err)
assert.Empty(t, file)
assert.Empty(t, raw)
assert.Len(t, pics, 0)
f, err = prepareTestBook1()
assert.NoError(t, err)
// Test get pictures with unsupported charset
path := "xl/drawings/drawing1.xml"
f.Pkg.Store(path, MacintoshCyrillicCharset)
_, _, err = f.getPicture(20, 5, path, "xl/drawings/_rels/drawing2.xml.rels")
_, err = f.getPicture(20, 5, path, "xl/drawings/_rels/drawing2.xml.rels")
assert.EqualError(t, err, "XML syntax error on line 1: invalid UTF-8")
f.Drawings.Delete(path)
_, _, err = f.getPicture(20, 5, path, "xl/drawings/_rels/drawing2.xml.rels")
_, err = f.getPicture(20, 5, path, "xl/drawings/_rels/drawing2.xml.rels")
assert.EqualError(t, err, "XML syntax error on line 1: invalid UTF-8")
}
@ -200,19 +197,20 @@ func TestAddDrawingPicture(t *testing.T) {
// Test addDrawingPicture with illegal cell reference
f := NewFile()
opts := &GraphicOptions{PrintObject: boolPtr(true), Locked: boolPtr(false)}
assert.EqualError(t, f.addDrawingPicture("sheet1", "", "A", "", "", 0, 0, image.Config{}, opts), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
assert.EqualError(t, f.addDrawingPicture("sheet1", "", "A", "", 0, 0, image.Config{}, opts), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
path := "xl/drawings/drawing1.xml"
f.Pkg.Store(path, MacintoshCyrillicCharset)
assert.EqualError(t, f.addDrawingPicture("sheet1", path, "A1", "", "", 0, 0, image.Config{}, opts), "XML syntax error on line 1: invalid UTF-8")
assert.EqualError(t, f.addDrawingPicture("sheet1", path, "A1", "", 0, 0, image.Config{}, opts), "XML syntax error on line 1: invalid UTF-8")
}
func TestAddPictureFromBytes(t *testing.T) {
f := NewFile()
imgFile, err := os.ReadFile("logo.png")
assert.NoError(t, err, "Unable to load logo for test")
assert.NoError(t, f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 1), "logo", ".png", imgFile, nil))
assert.NoError(t, f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 50), "logo", ".png", imgFile, nil))
assert.NoError(t, f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 1), &Picture{Extension: ".png", File: imgFile, Format: &GraphicOptions{AltText: "logo"}}))
assert.NoError(t, f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 50), &Picture{Extension: ".png", File: imgFile, Format: &GraphicOptions{AltText: "logo"}}))
imageCount := 0
f.Pkg.Range(func(fileName, v interface{}) bool {
if strings.Contains(fileName.(string), "media/image") {
@ -221,9 +219,9 @@ func TestAddPictureFromBytes(t *testing.T) {
return true
})
assert.Equal(t, 1, imageCount, "Duplicate image should only be stored once.")
assert.EqualError(t, f.AddPictureFromBytes("SheetN", fmt.Sprint("A", 1), "logo", ".png", imgFile, nil), "sheet SheetN does not exist")
assert.EqualError(t, f.AddPictureFromBytes("SheetN", fmt.Sprint("A", 1), &Picture{Extension: ".png", File: imgFile, Format: &GraphicOptions{AltText: "logo"}}), "sheet SheetN does not exist")
// Test add picture from bytes with invalid sheet name
assert.EqualError(t, f.AddPictureFromBytes("Sheet:1", fmt.Sprint("A", 1), "logo", ".png", imgFile, nil), ErrSheetNameInvalid.Error())
assert.EqualError(t, f.AddPictureFromBytes("Sheet:1", fmt.Sprint("A", 1), &Picture{Extension: ".png", File: imgFile, Format: &GraphicOptions{AltText: "logo"}}), ErrSheetNameInvalid.Error())
}
func TestDeletePicture(t *testing.T) {

View File

@ -581,8 +581,16 @@ type xdrTxBody struct {
P []*aP `xml:"a:p"`
}
// Picture maps the format settings of the picture.
type Picture struct {
Extension string
File []byte
Format *GraphicOptions
}
// GraphicOptions directly maps the format settings of the picture.
type GraphicOptions struct {
AltText string
PrintObject *bool
Locked *bool
LockAspectRatio bool