IPFS.GET -- can't display image using javascript

I am successfully uploading image to IPFS and getting its hash/CID back. Also from terminal, i can use IPFS get command to get back that image.

However, from javascript I am unable to load image. In browser its showing broken image. If you are unable to find bug in my code; I would really appreciate if you can share your working code for it, that is, reading image and displaying from ipfs cid using javascript.


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Party Profile</title>
</head>
<body>
    <h1> Party and Candidate Profile</h1>

    <div>
        <table id="candtable">
            <th>First Name</th>
            <th>Last Name</th>
            <th>Party Name</th>
            <th> Ethereum Address</th>
        </table>
    </div>

    <script type="text/javascript" src="./node_modules/web3/dist/web3.min.js"> </script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

    <script type="text/javascript" src="js/config/web3_config.js"></script>
    <script type="text/javascript" src="js/config/contracts_config.js"></script>
    
    <script src="https://cdn.jsdelivr.net/npm/ipfs-http-client/dist/index.min.js" integrity="sha384-TZd6uhEzw5ux5y56frZt2Qgtx3t9c1zblH4KWPELpvWtrQZHuYeZGyq6xO4cr0xJ" crossorigin="anonymous"></script>
    <script type="text/javascript" src="./js/config/ipfs_config.js"></script>
    <script type="text/javascript" src="./js/operations/profile_ipfs.js"></script>
</body>
</html>

Below is javascript file

function getCandidateProfile() {

  let params = new URLSearchParams(location.search);
  let partyname = params.get('v');
  console.log("Inside profile.js: " + partyname);

  CANDIDATE_ContractObject.methods.getCandidateDataFromPartyName(partyname).call((error, result) => {
    if (result) {
      console.log("Inside getCandidateDatafromPartyName: " + result);
      fillTableData(result);

    }
    else {
      console.log("Error in profile.js..." + error);
    }

  });
}

function fillTableData(ethAdd) {

  CANDIDATE_ContractObject.methods.readCandidateProfile(ethAdd).call((error, result) => {
    console.log("Inside fillTableData...Calling readCandidateProfile is ok..." + result[0]);
    $("#candtable").append("<tr><td>" + result[0] + "</td>" + "<td>" + "<img id='myimage' width='100' height='100'>" + "</td>" + "<td>" + result[2] + "</td>" + "<td>" + result[3] + "</td></tr>");
    var cid = result[1];
    console.log("contentID..." + cid);
    loadImage(cid);
  });
}

async function loadImage(newcid) {
  for await (const file of ipfs.ls(newcid)) {
    console.log("File path...ipfs.ls: " + file.path)
  }

  for await (const file of ipfs.cat(newcid)) {
    console.log("File path...ipfs.cat: " + file.path)
  }
  // https://github.com/ipfs/js-ipfs/blob/master/docs/core-api/FILES.md

  for await (const file of ipfs.get(newcid)) {
    console.log("Received cid: " + newcid)
    console.log("File path...ipfs.get: " + file.path)
    console.log(file)

    //files.forEach((file) => {
    console.log(file.path);

    const content = [];

    //for await (const chunk of file.content) {
    //  content.push(chunk);
    //}
    for await (const buf of ipfs.get(newcid)) {
      content.push(buf);
    }
    document.getElementById('myimage').src = URL.createObjectURL(
      new Blob(content, { type: 'image/jpg' } /* (1) */)
    );

    //let objectURL = URL.createObjectURL(new Blob(content, { type: 'image/jpeg' }));
    //let myImage = new Image();
    //myImage.src = objectURL;
    //document.getElementById('myimage').appendChild(myImage)
  }

}

function loadpage() {
  getCandidateProfile();
}

Hey @ziash , Iā€™m having a similar problem. Were you able to solve this issue? If so, could you me let me know how. Thanks in advance.

Hey @nic89 and @ziash, does this code help?

/** Uses `URL.createObjectURL` free returned ObjectURL with `URL.RevokeObjectURL` when done with it.
 * 
 * @param {string} cid CID you want to retrieve
 * @param {string} mime mimetype of image (optional, but useful)
 * @param {number} limit size limit of image in bytes
 * @returns ObjectURL
 */
async function loadImgURL(cid, mime, limit) {
    if (cid == "" || cid == null || cid == undefined) {
        return;
    }
    for await (const file of ipfs.get(cid)) {
        if (file.size > limit) {
            return;
        }
        const content = [];
        if (file.content) {
            for await(const chunk of file.content) {
                content.push(chunk);
            }
            return URL.createObjectURL(new Blob(content, {type: mime}));
        }
    }
}

Display with:

<body>
<img id="myImage" />
<script>
async function setImage() {
    // just an example, make sure to free the resulting ObjectURL when you're done with it
    //
    // if your CID doesn't work, try this one: Qmcm32sVsMYhURY3gqH7vSQ76492t5Rfxb3vsWCb35gVme
    // that's a popular CID, which should resolve every time
    document.getElementById("myImage").src = await loadImgURL("QmQqzMTavQgT4f4T5v6PWBp7XNKtoPmC9jvn12WPT3gkSE", "image/png", 524288);
}
setImage();
</script>
</body>
1 Like