2024-04-13 - How to upload an image to Hive Post?

in HiveDevs7 months ago (edited)

Attaching Images on a hive post

Hello Hive Community Members,

Welcome to daily updates from @sagarkothari88 - a Hive Witness & mobile-app-developer.

Actively contributing to following projects on Hive

Updates: HiveFreedomDollar

  • In this, right after payment is complete, App would suggest user to provide a feedback by uploading photos.
  • We would like to upload a photo to Hive.
  • That's what I focused on today.

How to upload an image to a Hive Blog Post?

  • https://developers.hive.io/services/imageHoster.html - Here the piece of code for uploading the image when you have the PostingKey.
  • I found some related code but not exact code to match my need - upload image with @HiveKeychain
  • In this article, I'll illustrate how to upload an image even with plain javascript inside html page.

Objective: Upload an image using HTML & vanilla JS

Step 1: Getting the Buffer & Axios

  • Yep. You read it write. We don't have the access to buffer on client-side-code.
  • This may look simple by looking at few lines of code but believe me, it took time to find out the right piece of code.
<body>
// this one to get the access to Buffer
<script  src="https://bundle.run/buffer@6.0.3"></script>

Step 2. Open File Picker

  • In my case, I've flutter on the front-end-side. So, I'll need to press the file button programmatically.
  • So, following code snippet illustrates launching file-picker from code.
  • You can remove unwanted code if you wish to.
async function openImagePickerForWebApp(id, account) {
    return new Promise(function (resolve, reject) {
        var input = document.createElement("input");
        input.type = "file";
        input.onchange = (e) => {
        };
        input.click();
    });
}
  • As you can see in the above code, we are creating input element.
  • We added input-type & added onchange handler there.
  • We clicked on that newly created element.

Step 3. Reading file using FileReader

  • As soon as user is done selecting the file (image file), we are required to take some action.
  • Following code snippet takes care of it.
async function openImagePickerForWebApp(id, account) {
    return new Promise(function (resolve, reject) {
        var input = document.createElement("input");
        input.type = "file";
        input.onchange = (e) => {
            var file = e.target.files[0];
            var reader = new FileReader();
            reader.onload = async () => {
            };
            reader.readAsBinaryString(file);
        };
        input.click();
    });
}
  • So, here we've defined file-reader & also defined variable file which is pointing to selected file.
  • We are setting up onload callback & right after that we're reading file as a binary string.

Step 4. Creating Buffers image upload

  • In order to avoid spam, Hive has implemented this mechanism
  • The image which is being uploaded, buffer of that image will be signed by private key of a user.
  • With this, only authenticated users can upload image.
// Step 1. Get Prefix Buffer
const prefix = window.buffer.Buffer.from("ImageSigningChallenge");
// Step 2. Get Buffer of selected File
const fileBuffer = window.buffer.Buffer.from(reader.result, "binary");
// Step 3. Concate / join both the buffers in right order
const buf = window.buffer.Buffer.concat([prefix, fileBuffer]);

Step 5. Get Buffer signed

  • Once you've the buffer ready, get it signed.
  • It depends on which authentication system you've implemented.
  • Your app can have @HiveAuth OR @HiveSigner or @HiveKeychain
  • I wouldn't recommend plain-key based logging in even if it's securely stored.
  • In this example, let's use @HiveKeychain.
  • If at all, you need code sample for @HiveAuth OR @HiveSigner, add a comment & I'll add another post or share code snippet in comment section.
window.hive_keychain.requestSignBuffer(account,JSON.stringify(buf),"Posting",(res) => {
    const url = `https://images.hive.blog/${account}/${res.result}`;
});
  • As soon as user approves signBuffer via @HiveKeychain, you get data in a call back
  • If you access to res.result, you'll find a signature.
  • This signature you can use for image uploading.
  • Here you can see, we have formed a URL with res.result
  • That URL, now can be used to upload the image.
  • NOTE: If signature isn't matching, upload may fail.

Step 6. Upload Image

const formData = new FormData();
formData.append("file", file, file.name);
const xhr = new XMLHttpRequest();
xhr.open("POST", url);
xhr.onload = () => {
    const res = JSON.parse(xhr.responseText);
    const uploadUrl = res.url;
    console.log(`Image Upload URL is - ${uploadUrl}`);
}

Full Code Snippet of an Image Upload Function

async function openImagePickerForWebApp(id, account) {
    return new Promise(function (resolve, reject) {
        var input = document.createElement("input");
        input.type = "file";
        input.onchange = (e) => {
            var file = e.target.files[0];
            var reader = new FileReader();
            reader.onload = async () => {
            const content = window.buffer.Buffer.from(reader.result,"binary");
            const prefix = window.buffer.Buffer.from("ImageSigningChallenge");
            const buf = window.buffer.Buffer.concat([prefix, content]);
            window.hive_keychain.requestSignBuffer(
                account, 
                JSON.stringify(buf), 
                "Posting", 
                (response) => {
                    const url = `https://images.hive.blog/${accountName}/${response.result}`;
                    const formData = new FormData();
                    formData.append("file", file, file.name);
                    const xhr = new XMLHttpRequest();
                    xhr.open("POST", url);
                    xhr.onload = () => {
                        const res = JSON.parse(xhr.responseText);
                        const uploadUrl = res.url;
                        console.log(`uploaded url is ${uploadUrl}`);
                    };
                });
            };
            reader.readAsBinaryString(file);
        };
        input.click();
    });
}

That's it?

  • Yes. that's it. One single function & it should do.
  • I'm not the HTML or Javascript Guy.
  • I like iOS App Development - Swift & I like Flutter.
  • For me, it really took good amount of time to not only figure it out but to put pieces together to make it work.
  • So, take a moment of appreciation, please don't forget to upvote the content or vote me as Hive Witness

Updates: HiveCurators - DiscordBot

  • HiveCurators - DiscordBot is doing well
  • No outages were reported
  • HiveCurators With DiscordBot was able to successfully curate approximately 42 posts today.
  • Curation report is added below in the post

Updates: Video Encoder Nodes

  • I'm running 12 powerful video encoder nodes for 3Speak Community Members.
  • Monthly internet bandwidth usage which exceeds 15 TB, Maintenance cost, Electricity backup, Internet backup, Depreciation cost - it's all on me.
  • Yesterday (12-Apr-2024) 3Speak published total 160 videos
  • My video encoder nodes encoded 140 videos from 160 videos published.

total

sagar-uploaded

How is @sagarKothari88 doing?

  • Health wise okay okay.
  • Mood off. My son fever is again spiking 102 F. Not liking it at all. Can't see him in weak & sobbing state.
  • We're paying a visit to doctor again tomorrow.
  • It's been long & we were thinking of going out somewhere nearby but I guess, that is not the case any more.
  • Today, afternoon when he was asleep after taking medicines, to lighten our mood, we watched first 2 episodes of Young Sheldon on Amazon Prime.
  • So, doctor's visit & more progress on HiveFreedomDollar app - that's it - weekend sorted 🥺

Curation Report

NOTE: If you don't like tagging you under curation report, let me know in comment section & I'll exclude you from the curation report.

AuthorPostWeight
@mysteriousroad@mysteriousroad/potato-panner-bites-recipe20 %
@preeti@preeti/torai-posto-ridge-gourd-with20 %
@floreudys79@floreudys79/gabriela-en-su-1era-presentacion20 %
@yagelybr@yagelybr/eng-esp-visiting-plaza-bolivar-and-its-surroundings-places-full-of-history20 %
@marlyncabrera@marlyncabrera/what-eases-my-mind-oror-kiss-104-on-me-time28 %
@bonzopoe@bonzopoe/reflexiones-innecesarias-084-aprender-a-escuchar-nuestras-tristezas-por-bonzopoe23 %
@tonyes@tonyes/esp-eng-soledad-solitud-o20 %
@theresa16@theresa16/my-veggie-shopping-beets-eng-esp20 %
@yraimadiaz@yraimadiaz/refreshing-guava-hibiscus-water-with-guava-espeng21 %
@stefano.massari@stefano.massari/13-04-2024-economy-profit-maximization-en-it32 %
@heroldius@heroldius/street-art-683-grills-fokus-fleo-omar-bernal-and-monke-montreal28 %
@enjar@enjar/cyberpunk-2077-or-the-untrustworthy-voodoos40 %
@passenger777@passenger777/oeluedeniz-eng-tr25 %
@slwzl@slwzl/first-dress-store-on-the-way-to-15-en-es21 %
@luchyl@luchyl/nature-in-vegetation-pobphotocontest-new-round-20 %
@eliezerfloyd@eliezerfloyd/los-ojos-del-alma-or-poema21 %
@charjaim@charjaim/memories-my-fathers-best-legacy20 %
@indiaunited@indiaunited/indiaunited-17129667369392.5 %
@jmis101@jmis101/when-it-s-not-normal20 %
@gidlark@gidlark/pavuki-40-spiders-4030 %
@yetaras@yetaras/mika-na-veronici31 %
@josediccus@josediccus/splinterlands-why-you-should-own-a-weapons-training-neutral-card-40 %
@nkemakonam89@nkemakonam89/away-from-work-promoting-extended-vacation-days25 %
@nitsuga12@nitsuga12/behind-the-thinker-3d-prints-of-a-masterpiece-eng-esp21 %
@costanza@costanza/playoffs-week-3-saturday-previews40 %
@littlesorceress@littlesorceress/contest-entry-smash-317-carnival21 %
@mamaemigrante@mamaemigrante/edificios-que-cuentan-una-historia23 %
@nadin-zakrevska@nadin-zakrevska/working-days-at-home-robochi22 %
@tub3r0@tub3r0/unleashing-venka-the-vile-a20 %
@goldenoakfarm@goldenoakfarm/after-the-storms-april-11-and-12-2024-goldenoakfarm26 %
@bradleyarrow@bradleyarrow/drip-day-building-update-1713-days-of-posting24 %
@papilloncharity@papilloncharity/after-the-storm40 %
@mayorkeys@mayorkeys/kgsnjccc21 %
@iskawrites@iskawrites/women-who-experience-menstrual-cramps-should-have-workplace-flexibility20 %
@randybpics@randybpics/momomad-monochromatic-photo-shoot-in-the-magic-forest-engesp20 %
@tattoodjay@tattoodjay/saturday-a-walk-on-popes-island40 %
@yameen@yameen/splinterlands-daily-rewards-or-purchased-and-opened-5-veteran-draws-or-got-2-epic-cards-or-04-12-202428 %
@steevc@steevc/11169723686-363085604540 %
@servelle@servelle/saturday-savers-club-2024-week-1635df84af60721 %
@mukund123@mukund123/kucoin-to-start-tds-deduction-in-india20 %
@sacra97@sacra97/love-the-clouds-199-sunset28 %
@ekavieka@ekavieka/losing-a-good-time27 %

What do you think?

  • What do you guys think?
  • Am I heading in right direction? Am I doing good for Hive?
  • Do you have some tips to share? If yes, add it in comment section.

Who am I?

  • I'm a Hive Witness
  • 3Speak App Developer
  • I've also contributed to mobile-app for HiveAuth
  • I also work on HiveFreedomDollar App
  • I worked with Team @ecency for integrating 3speak-video-upload feature
  • Founder of HiveCurators Community - @hive-185924/@hivecurators
  • Founder of https://the-hive-mobile.app/#/

Support me

  • Please upvote my content to motivate me
  • Please Reblog
  • Please vote me as Hive Witness

Vote me as Hive Witness


Support @sagarkothari88

color3speak.png

3Speak.tv3Speak Twitter3Speak Hive Blog3Speak Telegram
3Speak in SpanishDownload Android AppDownload iOS AppDownload Desktop App
Join 3Speak DiscordSetup Encoder NodeVote for SPK Network ProposalBadge Recipients
appStoreGooglePlayStore

Vote for 3Speak as Witness - Support @threespeak

Vote for Sagarkothari88 as Witness - Support @sagarkothari88

Sort:  

Thank you @bhattg for checking out my post & adding a comment.

Let me reward you back with !ALIVE token

@bhattg! You Are Alive so I just staked 0.1 $ALIVE to your account on behalf of @ sagarkothari88. (1/10)

The tip has been paid for by the We Are Alive Tribe through the earnings on @alive.chat, feel free to swing by our daily chat any time you want, plus you can win Hive Power (2x 50 HP) and Alive Power (2x 500 AP) delegations (4 weeks), and Ecency Points (4x 50 EP), in our chat every day.

You are welcome sir and thanks for the rewards 😁

Thank you @bhattg & Team @ecency
You guys are the best.

Support Back3Speak iOS3Speak Android

!BBH

Thank you @bradleyarrow for checking out the post & dropping BBH Token

Support Back3Speak iOS3Speak Android

You are welcome 😊

Thank you @bradleyarrow for checking out my post & adding a comment.

Let me reward you back with !ALIVE token

@bradleyarrow! You Are Alive so I just staked 0.1 $ALIVE to your account on behalf of @ sagarkothari88. (2/10)

The tip has been paid for by the We Are Alive Tribe through the earnings on @alive.chat, feel free to swing by our daily chat any time you want, plus you can win Hive Power (2x 50 HP) and Alive Power (2x 500 AP) delegations (4 weeks), and Ecency Points (4x 50 EP), in our chat every day.

@sagarkothari88! Your Content Is Awesome so I just sent 1 $BBH (Bitcoin Backed Hive) to your account on behalf of @bradleyarrow. (16/50)

appreciate a lot, going to use this sample to come up with something for my project. want to create some custom posts and was thinking about some images. My first thought was to pre upload it and use only the reference.

You're most welcome @vaipraonde
Wish that above code snippet would be useful to you.

All the best.

Support Back3Speak iOS3Speak Android

Thank you @vaipraonde for checking out my post & adding a comment.

Let me reward you back with !ALIVE token

@vaipraonde! You Are Alive so I just staked 0.1 $ALIVE to your account on behalf of @ sagarkothari88. (6/10)

The tip has been paid for by the We Are Alive Tribe through the earnings on @alive.chat, feel free to swing by our daily chat any time you want, plus you can win Hive Power (2x 50 HP) and Alive Power (2x 500 AP) delegations (4 weeks), and Ecency Points (4x 50 EP), in our chat every day.

// this one to call external APIs
<script  src="https://unpkg.com/axios/dist/axios.min.js"></script>

I would HIGHLY recommend using fetch over axios unless you need interceptors. You are loading another 16kb of data which does the same thing as a fetch but without needing to grab that 16kb.

Also if you are going to use axios, lock it to a specific version rather than using the latest, you never know when a breaking change is going to come around and break stuff.

Thank you @rishi556 for checking out my post & adding a comment.

Let me reward you back with !ALIVE token

@rishi556! You Are Alive so I just staked 0.1 $ALIVE to your account on behalf of @ sagarkothari88. (8/10)

The tip has been paid for by the We Are Alive Tribe through the earnings on @alive.chat, feel free to swing by our daily chat any time you want, plus you can win Hive Power (2x 50 HP) and Alive Power (2x 500 AP) delegations (4 weeks), and Ecency Points (4x 50 EP), in our chat every day.

Understood. Thanks for pointing it out. Initially I used fetch.
Then I thought of other devs who usually prefers axios (which includes me too :P)

I'll update it fetch. Also, any idea why code formatting isn't showing up correctly?
I remember adding perfect indentation - spacing - all gone :(

No idea on the code formatting, I thought it was strange too, maybe copy paste stuff?

Yeah, I used to use axios a ton myself too but have been moving my stuff over, especially now that it’s built into Node.JS too. I’ve been heavily working on UI stuff at work and so bundle size has become a huge concern to me.

Understood. Thank you for sharing your experience. I'll take a note of it & update code accordingly.

I'm 100% sure that, even after hitting the publish button, everything looked good & right after publishing, everything f**ked up. Let me try editing it from peakd.

Edited the post on Peakd & now it works fine.

Congratulations. You are one of the most active Hive developers. Keep going!

Thank you @seckorama for checking out my post & adding a comment.

Let me reward you back with !ALIVE token

@seckorama! You Are Alive so I just staked 0.1 $ALIVE to your account on behalf of @ sagarkothari88. (7/10)

The tip has been paid for by the We Are Alive Tribe through the earnings on @alive.chat, feel free to swing by our daily chat any time you want, plus you can win Hive Power (2x 50 HP) and Alive Power (2x 500 AP) delegations (4 weeks), and Ecency Points (4x 50 EP), in our chat every day.

Thank you very much, @sagarkothari88. 👍 !BEER

 7 months ago Reveal Comment

Thank you @seckorama for motivating words.

I'll keep up my best.

Support Back3Speak iOS3Speak Android

Thanks @bhattg and @sagarkothari88 for the curation, it's appreciated.
Enjoy your weekend

You're welcome.

Thank you @heroldius for checking out my post & adding a comment.

Let me reward you back with !ALIVE token

Support Back3Speak iOS3Speak Android

@heroldius! You Are Alive so I just staked 0.1 $ALIVE to your account on behalf of @ sagarkothari88. (3/10)

The tip has been paid for by the We Are Alive Tribe through the earnings on @alive.chat, feel free to swing by our daily chat any time you want, plus you can win Hive Power (2x 50 HP) and Alive Power (2x 500 AP) delegations (4 weeks), and Ecency Points (4x 50 EP), in our chat every day.

Thank you, thank you! For your work and consideration, always 💙

You are welcome @marlyncabrera

Thank you for checking out my post & adding a comment.

Let me reward you back with !ALIVE token

Support Back3Speak iOS3Speak Android

@marlyncabrera! You Are Alive so I just staked 0.1 $ALIVE to your account on behalf of @ sagarkothari88. (4/10)

The tip has been paid for by the We Are Alive Tribe through the earnings on @alive.chat, feel free to swing by our daily chat any time you want, plus you can win Hive Power (2x 50 HP) and Alive Power (2x 500 AP) delegations (4 weeks), and Ecency Points (4x 50 EP), in our chat every day.

This post has been manually curated by @bhattg from Indiaunited community. Join us on our Discord Server.

Do you know that you can earn a passive income by delegating to @indiaunited. We share more than 100 % of the curation rewards with the delegators in the form of IUC tokens. HP delegators and IUC token holders also get upto 20% additional vote weight.

Here are some handy links for delegations: 100HP, 250HP, 500HP, 1000HP.

image.png

100% of the rewards from this comment goes to the curator for their manual curation efforts. Please encourage the curator @bhattg by upvoting this comment and support the community by voting the posts made by @indiaunited.


You've been curated by @plantpoweronhive! Delegations welcome!

Find our community here | Curation Trail

Thank you @plantpoweronhive

Thank you for checking out my post & adding a comment.

Let me reward you back with !ALIVE token

Support Back3Speak iOS3Speak Android

@plantpoweronhive! You Are Alive so I just staked 0.1 $ALIVE to your account on behalf of @ sagarkothari88. (5/10)

The tip has been paid for by the We Are Alive Tribe through the earnings on @alive.chat, feel free to swing by our daily chat any time you want, plus you can win Hive Power (2x 50 HP) and Alive Power (2x 500 AP) delegations (4 weeks), and Ecency Points (4x 50 EP), in our chat every day.

Thank you for the mention, my friend! Great report!

You are most welcome @littlesorceress

Bit too technical for me to understand Sagar bhai 😁

But I do have a question which I think you can address

Is there image size limit while uploading it via Hive Web?

I had a couple of 19/20MB sized images and no matter what I did, I always got upload error

Greetings friend, it seems a little late but I went through this publication and I think it is a real treasure for those who are trying to get into Hive, Thank you for sharing,
One question, where did this come from https://bundle.run/buffer@6.0.3" and https://images.hive.blog is public, so I can upload images to through it without having my own Imagenhoster instance, Thanks again, I don't understand why the hive documentation is not as good as this post