@@ -98,16 +98,31 @@ export function createViewContextMenu(reader, params) {
9898 onCommand : ( ) => {
9999 navigator . clipboard . writeText ( params . overlay . url ) ;
100100 }
101- }
102- ] ,
103- [
101+ } ,
104102 {
105103 label : reader . _getString ( 'general-copy' ) ,
106104 disabled : ! ( params . overlay && params . overlay . type === 'math' && ! reader . canCopy ) ,
107105 onCommand : ( ) => {
108106 navigator . clipboard . writeText ( params . overlay . tex ) ;
109107 }
110- }
108+ } ,
109+ {
110+ label : reader . _getString ( 'reader-copy-image' ) ,
111+ disabled : ! ( params . overlay && params . overlay . type === 'image' && ! reader . canCopy
112+ && typeof navigator . clipboard . write === 'function' ) ,
113+ onCommand : async ( ) => {
114+ // Browsers generally only support image/png in the Clipboard API,
115+ // so use a canvas to convert to PNG
116+ let bitmap = await createImageBitmap ( params . overlay . image ) ;
117+ let canvas = new OffscreenCanvas ( bitmap . width , bitmap . height ) ;
118+ let ctx = canvas . getContext ( 'bitmaprenderer' ) ;
119+ ctx . transferFromImageBitmap ( bitmap ) ;
120+ let blob = await canvas . convertToBlob ( { type : 'image/png' } ) ;
121+ await navigator . clipboard . write ( [
122+ new ClipboardItem ( { [ blob . type ] : blob } )
123+ ] ) ;
124+ }
125+ } ,
111126 ] ,
112127 [
113128 {
@@ -116,6 +131,21 @@ export function createViewContextMenu(reader, params) {
116131 onCommand : ( ) => reader . copy ( )
117132 }
118133 ] ,
134+ [
135+ ( reader . _platform === 'zotero' || window . dev ) && {
136+ label : reader . _getString ( 'reader-save-image-as' ) ,
137+ disabled : ! ( params . overlay && params . overlay . type === 'image' ) ,
138+ onCommand : async ( ) => {
139+ // onSaveImageAs() expects PNG
140+ let bitmap = await createImageBitmap ( params . overlay . image ) ;
141+ let canvas = new OffscreenCanvas ( bitmap . width , bitmap . height ) ;
142+ let ctx = canvas . getContext ( 'bitmaprenderer' ) ;
143+ ctx . transferFromImageBitmap ( bitmap ) ;
144+ let blob = await canvas . convertToBlob ( { type : 'image/png' } ) ;
145+ reader . _onSaveImageAs ( blob ) ;
146+ } ,
147+ }
148+ ] ,
119149 [
120150 {
121151 label : reader . _getString ( 'reader-zoom-in' ) ,
0 commit comments