because I was tired of manually uploading the screenshots to an image hoster for my forum posts, this module was created.
Module ImgBBUploader:
The module makes it possible to automatically upload an image to the webspace of the image hoster http://www.ImgBB.com and returns the following three links if transfer was successful:
- Link to the image (in the ImgBB web page preview)
- Link to image (direct link)
- Link to delete the image
The module offers the following public procedure for this purpose:
Code: Select all
Procedure.i ImgBBUpload(sImageFile.s, sAPIKey.s, *stOutImgBBResult.ImgBBResult)
; +-----------------------------------------------------------------
; |Description : Automatically uploads an image to the image hoster www.ImgBB.com
; | The Imagehoster supports the image formats JPG, PNG, BMP and GIF with a maximum size of 16 MB.
; |Arguments : sImageFile : The full path and filename of the image
; | sAPIKey : The ImgBB.com API key, wich is necessary for the upload to work
; | stOutImgBBResult: A structured return variable of type ImgBBResult containing
; | the links to the uploaded image (preview link, direct link, delete link)
; |Results : 1, if the upload was successful, otherwise 0.
; |Remarks : -
; +-----------------------------------------------------------------
Code: Select all
Structure ImgBBResult
sFileStatus.s ; "Ok" = ok
sHttpStatus.s ; "200" = ok
sUploadSuccessfull.s ; true / false
sViewerLink.s
sDirectLink.s
sDeleteLink.s
EndStructure
To be able to use the API you have to register a user account and then you can get an API key in your profile. The API key can be displayed at the push of a button and used immediately. I can reassure paranoid people like me, because you can also create the account with a funny disposable email address and a fictional username.
There is also a checkbox [x] private mode in the profile. I didn't find a function on ImgBB that would allow you to view pictures of other users, but to be on the safe side you should set this checkbox.
At the end of the module I added an example program, which is encapsulated by CompilerIf #PB_Compiler_IsMainFile. The example program is actually a full-fledged upload program. I intentionally made it a bit more extensive, because I can use it as an uploader for myself.
The example program uses a demo API key registered by me (yes of course, the account was created with a fantasy email address). You should, however, request your own API key if you use the module permanently. It is possible that the demo API key will be blocked very quickly if too many people use it or if some jokers upload inappropriate images. According to ImgBB.com, the images are checked by humans and must comply with ImgBB.com's terms of use (see also https://imgbb.com/tos).
Here is a screenshot of the example program...
Changelog:
Code: Select all
;* 1.01 - rel 01.05.2019:
;* fix - A closeFile() command was missing in the error handling (in line 174)
Code: Select all
;*************************************************************************
;* ImgBBUploader (c) Kurzer
;*************************************************************************
;*
;* Modulname : ImgBBUploader
;* Filename : mod_ImgBBUploader.pbi
;* Filetype : Module [MainApp, Formular, Include, Module, Data]
;* Programming lang. : Purebasic 5.70+ Minimum because of HTTPRequest()
;* String-Format : Unicode [Ascii, Unicode, All]
;* Platform : Windows [Windows, Mac, Linux, All]
;* Processor : All [x86, x64, All]
;* Compileroptions : -
;* Version : 1.01
;* Date : 01.05.2019
;* Autor : Kurzer
;* Dependencies :
;* -----------------------------------------------------------------------
;* Description:
;*
;* Uploads an image to the image hoster www.ImgBB.com
;*
;* Attention: You need an own API key from www.ImgBB.com and have to register
;* a user account. The example at the end of this module uses an API key which
;* will be probably blocked if it is used too often. So you better get your
;* own API key at https://api.imgbb.com/
;*
;* The image hoster supports the image formats JPG, PNG, BMP and GIF with a
;* maximum size of 16 MB.
;*
;* Please respect the ImgBB's terms of use: https://imgbb.com/tos
;*
;* For legal consequences arising from the use of this module (especially if
;* the user uploads non-compliant images), the user of this module alone is
;* responsible and in no way the author of the module!
;* -----------------------------------------------------------------------
;* Changelog:
;* 1.01 - rel 01.05.2019:
;* fix - A closeFile() command was missing in the error handling (in line 174)
;* 1.00 - rel 22.04.2019:
;* add - First release
;* -----------------------------------------------------------------------
;* English-Forum : https://www.purebasic.fr/english/viewtopic.php?f=27&t=72696
;* French-Forum :
;* German-Forum : https://www.purebasic.fr/german/viewtopic.php?f=8&t=31417
;* -----------------------------------------------------------------------
;* License: MIT License
;*
;* Copyright (c) 2016/19 Kurzer
;*
;* Permission is hereby granted, free of charge, to any person obtaining a copy
;* of this software and associated documentation files (the "Software"), to deal
;* in the Software without restriction, including without limitation the rights
;* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
;* copies of the Software, and to permit persons to whom the Software is
;* furnished to do so, subject to the following conditions:
;*
;* The above copyright notice and this permission notice shall be included in all
;* copies or substantial portions of the Software.
;*
;* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
;* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
;* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
;* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
;* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
;* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
;* SOFTWARE.
;*
;* ---------------- German translation of the MIT License ----------------
;*
;* MIT Lizenz:
;*
;* Hiermit wird unentgeltlich jeder Person, die eine Kopie der Software und der
;* zugehörigen Dokumentationen (die "Software") erhält, die Erlaubnis erteilt,
;* sie uneingeschränkt zu nutzen, inklusive und ohne Ausnahme mit dem Recht, sie
;* zu verwenden, zu kopieren, zu verändern, zusammenzufügen, zu veröffentlichen,
;* zu verbreiten, zu unterlizenzieren und/oder zu verkaufen, und Personen, denen
;* diese Software überlassen wird, diese Rechte zu verschaffen, unter den folgenden
;* Bedingungen:
;*
;* Der obige Urheberrechtsvermerk und dieser Erlaubnisvermerk sind in allen Kopien
;* oder Teilkopien der Software beizulegen.
;*
;* DIE SOFTWARE WIRD OHNE JEDE AUSDRÜCKLICHE ODER IMPLIZIERTE GARANTIE BEREITGESTELLT,
;* EINSCHLIEßLICH DER GARANTIE ZUR BENUTZUNG FÜR DEN VORGESEHENEN ODER EINEM BESTIMMTEN
;* ZWECK SOWIE JEGLICHER RECHTSVERLETZUNG, JEDOCH NICHT DARAUF BESCHRÄNKT. IN KEINEM
;* FALL SIND DIE AUTOREN ODER COPYRIGHTINHABER FÜR JEGLICHEN SCHADEN ODER SONSTIGE
;* ANSPRÜCHE HAFTBAR ZU MACHEN, OB INFOLGE DER ERFÜLLUNG EINES VERTRAGES, EINES DELIKTES
;* ODER ANDERS IM ZUSAMMENHANG MIT DER SOFTWARE ODER SONSTIGER VERWENDUNG DER SOFTWARE
;* ENTSTANDEN.
;*************************************************************************
DeclareModule ImgBBUpload
;- --- [Module declaration / public elements] ------------------------------------------
;-
;*************************************************************************
;- Compiler directives
;*************************************************************************
EnableExplicit
;*************************************************************************
;- Structures
;*************************************************************************
Structure ImgBBResult
sFileStatus.s ; "Ok" = ok
sHttpStatus.s ; "200" = ok
sUploadSuccessfull.s ; true / false
sViewerLink.s
sDirectLink.s
sDeleteLink.s
EndStructure
;*************************************************************************
;- Public Procedures (dec)
;*************************************************************************
Declare.i ImgBBUpload(sImageFile.s, sAPIKey.s, *stOutImgBBResult.ImgBBResult)
EndDeclareModule
Module ImgBBUpload
;-
;- --- [Module implementation / private elements] -----------------------------------------
;-
;*************************************************************************
;- Constants
;*************************************************************************
#IMGBB_URL = "https://api.imgbb.com/1/upload?key=#APIKEY#"
#IMGBB_PARAMS = "image="
;*************************************************************************
;- Private Procedures (imp)
;*************************************************************************
;*************************************************************************
;- Public Procedures (imp)
;*************************************************************************
Procedure.i ImgBBUpload(sImageFile.s, sAPIKey.s, *stOutImgBBResult.ImgBBResult)
; +-----------------------------------------------------------------
; |Description : Automatically uploads an image to the image hoster www.ImgBB.com
; | The Imagehoster supports the image formats JPG, PNG, BMP and GIF with a maximum size of 16 MB.
; |Arguments : sImageFile : The full path and filename of the image
; | sAPIKey : The ImgBB.com API key, wich is necessary for the upload to work
; | stOutImgBBResult: A structured return variable of type ImgBBResult containing
; | the links to the uploaded image (preview link, direct link, delete link)
; |Results : 1, if the upload was successful, otherwise 0.
; |Remarks : -
; +-----------------------------------------------------------------
Protected.i *Buffer, iImgFile, iLength, iHttpRequest, iJson
Protected.s sUrl, sParams, sImageB64, sResponse
; Check file extension
Select LCase(GetExtensionPart(sImageFile))
Case "jpg", "png", "bmp", "gif"
; Do nothing, because format is okay
Default
*stOutImgBBResult\sFileStatus = "File format error"
ProcedureReturn 0
EndSelect
; Open Image file
iImgFile = ReadFile(#PB_Any, sImageFile)
If iImgFile = 0
*stOutImgBBResult\sFileStatus = "File open error"
ProcedureReturn 0
EndIf
iLength = Lof(iImgFile)
If iLength < 1
*stOutImgBBResult\sFileStatus = "File length error"
CloseFile(iImgFile)
ProcedureReturn 0
EndIf
; Allocate a memory buffer, load the image into the buffer and encode it to Base64
*Buffer = AllocateMemory(iLength)
If *Buffer = 0
*stOutImgBBResult\sFileStatus = "File buffer error"
CloseFile(iImgFile)
ProcedureReturn 0
EndIf
iLength = ReadData(iImgFile, *Buffer, iLength)
CloseFile(iImgFile)
If iLength = 0
*stOutImgBBResult\sFileStatus = "File read error"
FreeMemory(*Buffer)
ProcedureReturn 0
EndIf
sImageB64 = Base64Encoder(*Buffer, iLength)
FreeMemory(*Buffer)
*stOutImgBBResult\sFileStatus = "Ok"
; Send image to image hoster
sURL = #IMGBB_URL
sURL = ReplaceString(sURL, "#APIKEY#", sAPIKey)
sParams = URLEncoder(#IMGBB_PARAMS + sImageB64, #PB_UTF8)
iHttpRequest = HTTPRequest(#PB_HTTP_Post, sURL, sParams)
If iHttpRequest = 0
*stOutImgBBResult\sHttpStatus = "HTTPRequest error"
ProcedureReturn 0
EndIf
; Check status code of the Http request
*stOutImgBBResult\sHttpStatus = HTTPInfo(iHttpRequest, #PB_HTTP_StatusCode)
If *stOutImgBBResult\sHttpStatus <> "200"
FinishHTTP(iHttpRequest)
ProcedureReturn 0
EndIf
sResponse = HTTPInfo(iHttpRequest, #PB_HTTP_Response)
sResponse = ReplaceString(sResponse, "\/", "/")
FinishHTTP(iHttpRequest)
; Extract JSON data
iJson = ParseJSON(#PB_Any, sResponse)
If iJson = 0
*stOutImgBBResult\sUploadSuccessfull = "false"
ProcedureReturn 0
EndIf
; Check if the upload is flagged as successfully by the image hoster
If GetJSONBoolean(GetJSONMember(JSONValue(iJson), "success")) = 1
*stOutImgBBResult\sUploadSuccessfull = "true"
Else
*stOutImgBBResult\sUploadSuccessfull = "false"
FreeJSON(iJson)
ProcedureReturn 0
EndIf
*stOutImgBBResult\sViewerLink = GetJSONString(GetJSONMember(GetJSONMember(JSONValue(iJson), "data"), "url_viewer"))
*stOutImgBBResult\sDirectLink = GetJSONString(GetJSONMember(GetJSONMember(JSONValue(iJson), "data"), "url"))
*stOutImgBBResult\sDeleteLink = GetJSONString(GetJSONMember(GetJSONMember(JSONValue(iJson), "data"), "delete_url"))
FreeJSON(iJson)
ProcedureReturn 1
EndProcedure
EndModule
;-------------------------------------------------------------------------------
;- Main
CompilerIf #PB_Compiler_IsMainFile
EnableExplicit
#StatusMsg = "Drag 'n drop an image file into the red circle"
#DemoAPIKey = "33f1af445879b680577710583e8ec7b0" ; 33f1af445879b680577710583e8ec7b0
Enumeration
#Window = 0
#Image = 0
#ImageGadget = 0
#TextStatus
#TextViewer
#StringViewer
#ButtonViewer
#TextDirect
#StringDirect
#ButtonDirect
#TextDelete
#StringDelete
#ButtonDelete
#TextAPI
#StringAPI
EndEnumeration
Global.i iImageSize = DesktopScaledX(100)
Procedure UploadFile()
UseModule ImgBBUpload
Protected stImgBBResult.ImgBBResult
Protected.s sFileName, sMessage
sFileName = EventDropFiles()
If FileSize(sFileName) > 0
TextGadget(#TextStatus, 5, 112, 250, 20, "Uploading image, please wait...")
If ImgBBUpload(sFilename, #DemoAPIKey, stImgBBResult)
Debug "File status: " + stImgBBResult\sFileStatus
Debug "Http status: " + stImgBBResult\sHttpStatus
Debug "Upload status: " + stImgBBResult\sUploadSuccessfull
SetGadgetText(#StringViewer, stImgBBResult\sViewerLink)
SetGadgetText(#StringDirect, stImgBBResult\sDirectLink)
SetGadgetText(#StringDelete, stImgBBResult\sDeleteLink)
Else
TextGadget(#TextStatus, 5, 112, 250, 20, "Error during image upload!")
sMessage + "File status: " + #TAB$ + stImgBBResult\sFileStatus + #LF$
sMessage + "Http status: " + #TAB$ + stImgBBResult\sHttpStatus + #LF$
sMessage + "Upload status: " + #TAB$ + stImgBBResult\sUploadSuccessfull
MessageRequester("Upload failed - Image upload to ImgBB.com", sMessage, #PB_MessageRequester_Error|#PB_MessageRequester_Ok)
EndIf
TextGadget(#TextStatus, 5, 112, 250, 20, #StatusMsg)
EndIf
UnuseModule ImgBBUpload
EndProcedure
Procedure Copy()
Select EventGadget()
Case #ButtonViewer
SetClipboardText(GetGadgetText(#StringViewer))
Case #ButtonDirect
SetClipboardText(GetGadgetText(#StringDirect))
Case #ButtonDelete
SetClipboardText(GetGadgetText(#StringDelete))
EndSelect
EndProcedure
Procedure.i CreateDropImage(iImageNo.i)
If CreateImage(iImageNo, iImageSize, iImageSize) And StartDrawing(ImageOutput(iImageNo))
Box(0, 0, iImageSize, iImageSize, $ffffff)
Circle(iImageSize/2, iImageSize/2, iImageSize/2.2, $0000ee)
Circle(iImageSize/2, iImageSize/2, iImageSize/3.2, $ffffff)
Circle(iImageSize/2, iImageSize/2, iImageSize/6, $0000ee)
StopDrawing()
ProcedureReturn 1
EndIf
ProcedureReturn 0
EndProcedure
Procedure Main()
InitNetwork()
If OpenWindow(#Window, 600, 100, 410, 130, "Image upload to ImgBB.com by Kurzer", #PB_Window_MinimizeGadget)
StickyWindow(#Window, 1)
If CreateDropImage(#Image)
ImageGadget(#ImageGadget, 5, 5, iImageSize, iImageSize, ImageID(#Image), #PB_Image_Border)
EnableGadgetDrop(#ImageGadget, #PB_Drop_Files, #PB_Drag_Copy)
TextGadget(#TextStatus, 5, 112, 250, 20, #StatusMsg)
TextGadget(#TextViewer, 120, 7, 70, 20, "Viewer link:")
StringGadget(#StringViewer, 190, 5, 165, 20, "", #PB_String_ReadOnly)
ButtonGadget(#ButtonViewer, 360, 5, 45, 20, "Copy")
TextGadget(#TextDirect, 120, 30, 70, 20, "Direct link:")
StringGadget(#StringDirect, 190, 28, 165, 20, "", #PB_String_ReadOnly)
ButtonGadget(#ButtonDirect, 360, 30, 45, 20, "Copy")
TextGadget(#TextDelete, 120, 53, 70, 20, "Delete link:")
StringGadget(#StringDelete, 190, 51, 165, 20, "", #PB_String_ReadOnly)
ButtonGadget(#ButtonDelete, 360, 53, 45, 20, "Copy")
TextGadget(#TextAPI, 120, 82, 70, 20, "Your API key:")
StringGadget(#StringAPI, 190, 80, 215, 20, #DemoAPIKey, #PB_String_ReadOnly)
BindEvent(#PB_Event_GadgetDrop, @UploadFile(), 0, 0)
BindGadgetEvent(#ButtonViewer, @Copy(), #PB_EventType_LeftClick)
BindGadgetEvent(#ButtonDirect, @Copy(), #PB_EventType_LeftClick)
BindGadgetEvent(#ButtonDelete, @Copy(), #PB_EventType_LeftClick)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
UnbindEvent(#PB_Event_GadgetDrop, @UploadFile(), 0, 0)
UnbindGadgetEvent(#ButtonViewer, @Copy(), #PB_EventType_LeftClick)
UnbindGadgetEvent(#ButtonDirect, @Copy(), #PB_EventType_LeftClick)
UnbindGadgetEvent(#ButtonDelete, @Copy(), #PB_EventType_LeftClick)
FreeImage(#Image)
FreeGadget(#PB_All)
EndIf
CloseWindow(#Window)
EndIf
EndProcedure
Main()
End
CompilerEndIf
Greetings Kurzer