It is currently Tue Mar 31, 2020 8:07 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 6 posts ] 
Author Message
 Post subject: Module: Automatic image upload to ImgBB.com
PostPosted: Mon Apr 22, 2019 1:45 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Jun 11, 2006 12:07 am
Posts: 551
Location: Near Hamburg | Status: Currently not active in programming.
Hello,

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:
   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      : -
      ; +-----------------------------------------------------------------

The result variable in which the links to the image are transferred after a successful image upload must be of type ImgBBResult:
Code:
   Structure ImgBBResult
      sFileStatus.s                     ; "Ok" = ok
      sHttpStatus.s                     ; "200" = ok
      sUploadSuccessfull.s            ; true / false
      sViewerLink.s
      sDirectLink.s
      sDeleteLink.s
   EndStructure

I chose ImgBB.com because this image hoster offers an API to upload. So I can easily upload a Base64 encoded image with HTTPReqeust and get back a JSON result with the necessary links and status values.

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. 8)

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. :-)
Image

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...
Image

Changelog:
Code:
;* 1.01 - rel 01.05.2019:
;*        fix - A closeFile() command was missing in the error handling (in line 174)


... and the sourcecode:
Code:
;*************************************************************************
;* 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

Have fun with this module

Greetings Kurzer

_________________
PB 5.71 x64, OS: Windows 7 Pro x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520, User age: 51y
"Happiness is a pet." | "Never run a changing system!"


Last edited by kurzer on Fri May 03, 2019 9:22 am, edited 3 times in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Module: Automatic image upload to ImgBB.com
PostPosted: Mon Apr 22, 2019 3:12 pm 
Offline
Addict
Addict
User avatar

Joined: Sun Nov 05, 2006 11:42 pm
Posts: 4658
Location: Lyon - France
Very usefull idea :idea:
Works great here, simpler would be indecent :D
Thanks for sharing 8)

_________________
ImageThe happiness is a road...
Not a destination


Top
 Profile  
Reply with quote  
 Post subject: Re: Module: Automatic image upload to ImgBB.com
PostPosted: Mon Apr 22, 2019 3:47 pm 
Offline
Addict
Addict

Joined: Thu Jun 07, 2007 3:25 pm
Posts: 3792
Location: Berlin, Germany
Cool idea, thanks for sharing!

_________________
Please excuse my flawed English. My native language is PureBasic.
Search
RSBasic's backups


Top
 Profile  
Reply with quote  
 Post subject: Re: Module: Automatic image upload to ImgBB.com
PostPosted: Tue Apr 23, 2019 4:29 am 
Offline
Enthusiast
Enthusiast

Joined: Mon May 10, 2010 4:02 pm
Posts: 153
Works great!
Thanks for sharing!


Top
 Profile  
Reply with quote  
 Post subject: Re: Module: Automatic image upload to ImgBB.com
PostPosted: Wed May 01, 2019 12:32 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Jun 11, 2006 12:07 am
Posts: 551
Location: Near Hamburg | Status: Currently not active in programming.
Thank you very much for your feedback. Image

I just fixed a small bug. The code in the first post has been updated.

Code:
;* 1.01 - rel 01.05.2019:
;*        fix - A closeFile() command was missing in the error handling (in line 174)

_________________
PB 5.71 x64, OS: Windows 7 Pro x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520, User age: 51y
"Happiness is a pet." | "Never run a changing system!"


Top
 Profile  
Reply with quote  
 Post subject: Re: Module: Automatic image upload to ImgBB.com
PostPosted: Tue Dec 17, 2019 11:43 pm 
Offline
New User
New User

Joined: Tue Dec 17, 2019 11:33 pm
Posts: 1
Great program Kurzer!

Just would like to provide this modification/suggestion to pass the filename. Just change the line that sets sParams to:

sParams = URLEncoder("name=" + Left(GetFilePart(sImageFile),Len(GetFilePart(sImageFile))-4) + "&" + #IMGBB_PARAMS + sImageB64, #PB_UTF8)

-Jose


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye