Sunday, March 4, 2018

How to Embed Pixiv Images

Since I've been embedding a dozen of Pixiv images in this blog for reference, I'm going to go off-topic for a bit to show how to embed these things.

Now, you might be asking: why would anyone want to embed them instead of just infringing copyright uploading it to somewhere else? Well, there are pros and cons

The pros are:
  • If the artist deletes the post from Pixiv, it'll automatically disappear from your website, respectfully.
  • Spend less bandwidth because the images are hosted on Pixiv.

The cons are:
  • If the artist deletes the post from Pixiv, it will disappear from your posts.
    (note: this actually happened to be, so for example images I steer away from using images posted recently and take the ones posted from years ago instead.)
  • If the post is deleted by Pixiv mods, the embedded images disappear too.
  • If the artist is banned from Pixiv, the embedded images disappear too.
  • If the artist updates their post the image may change into something you don't want.
  • If the artist's account is hacked the hacker may changed all his post images into something you really don't want.
  • Takes longer to load the page because the browser has to access multiple websites.
  • Needs to load a script to load a image instead of just loading the image.
  • Embedded synchronously causes the page to render only partially until the script loads.
  • In the unlikely event Pixiv is hacked and somebody replaces the script with a malicious script, the malware will be spread all over your posts.
  • In the unlikely event Pixiv is hacked and somebody deletes the database and they don't have a backup (which I'd like to say is unlikely, but can't because some people just don't do backups.) then your embedded images disappear.
  • In the event Pixiv stops supporting embedded images with the script, the embedded images disappear.
  • If Pixiv goes down, your embedded images disappear.
  • If Pixiv goes under, your embedded images disappear.
  • You can only choose three different sizes for the images (small, medium, large), although you can resize them arbitrarily with CSS voodoo.
  • In certain content editors (forums, some free blogs) adding user scripts is forbidden so the embedding is impossible anyway.

First Steps

First off, create an account on Pixiv, or sign in in your account if you had created one and couldn't figure out Pixiv, or just use the Pixiv account you use everyday and you don't even know whether it's possible to log off from.

Anyway you need to be logged in because Pixiv shows a different page depending on whether you're logged in or not, and the embed code only shows up if you're logged in.

Then go after some random Pixiv image, say, of your waifu, for example.

Getting The Embed Code

After you get to the Pixiv submission you want to embed, scroll down to the comment area. On the right side there'll be a box showing the share code and embed script.

Screenshot of pixiv showing the location of the embed script code.

An embed script should look somewhat like this:

<script src="" data-id="46118362_e92a647082372e6944a875cb4d51c9b4" data-size="medium" data-border="on" charset="utf-8"></script><noscript><p><a href=";illust_id=46118362" target="_blank">さばげぶっ!観始めました</a> by <a href="" target="_blank">さかき@妖精領域</a> on <a href="" target="_blank">pixiv</a></p></noscript>

Broken down:
  1. The script embed.js, with a data-id, data-size and data-border attributes.
  2. A noscript element for user agents that have disabled or don't support scripting.
  3. Inside a paragraph element.
  4. Inside which are links that open to a new tab.

To be honest I think there are too many links so I usually removed the artist and Pixiv links from the code and leave only the link to the submission.

Customizing The Embed

The attributes data-size and data-border can be changed to modify somewhat how the embed looks. This can be done the Pixiv page through the box below the embed code.

The width of the embed without and with the border are:
  • Small: 150px vs. 220px.
  • Medium: 240px vs. 390px.
  • Large: 600px vs. 700px.

These values are up-to. If the aspect ratio of a submission is too tall, the width will be smaller.

The medium with border is over 390px, so it won't fit inside some mobile resolutions.

Small Size

data-border="off" data-size="small"


Small With Border

data-border="on" data-size="small"

Medium Size

data-border="off" data-size="medium"


Medium With Border

data-border="on" data-size="medium"

Large Size

data-border="off" data-size="large"


Large With Border

data-border="on" data-size="large"

Center Aligning

You may have noticed that by default the embedded images are left-aligned, not center-aligned, and that may totally screw up with the feng shui of your website design or blog template.

Fortunately, all the script does is embed an iframe which contains an image. Since an iframe is an inline-frame, it's treated like text as far as CSS is concerned, which means we can align it like text

For example, with the code:

<div style="text-align: center;">EMBED CODE GOES HERE</div>

Of course, you can also use classes if you want.


Removing Text

When you embed images by script, the script embeds not only the image itself, but also an attribution text that says the title, the author, the date posted, and that it came from Pixiv. That's a load of useless information given that you can just click on the image to go see it on Pixiv anyway.

Fortunately, it's possible to make the text disappear by using CSS classes.

The title of the submission is classed .pixiv-embed-title.
The other information is classed .pixiv-embed-meta.

So the following CSS code removes both:

.pixiv-embed-title, .pixiv-embed-meta { display: none; }

Of course, if you want some embeds to show the title and some to not show the titles, you can just wrap them in a div with a class to switch it on and off. For example:

.no-pixiv-title-pls .pixiv-embed-title { display: none; }
.no-pixiv-meta-pls .pixiv-embed-meta { display: none; }
<div class="no-pixiv-title-pls">NO TITLE</div>
<div class="no-pixiv-meta-pls">NO META</div>
<div class="no-pixiv-title-pls no-pixiv-meta-pls">NO TITLE NO META</div>

Kuuhaku never loses.


You can combine the techniques above to create a gallery-like thingy from Pixiv thumbnails by putting them centered side-by-side without text.

The only thing missing from the equation is that the container of the entire embed created by the script, a div classed pixiv-embed, is, well, a div, and so it's display: block by default, which means that by default it occupies the whole horizontal space.

If we want to put images side-by-side, we need to make it not occupy the entirety of the horizontal space, and this can be done by using display: inline-block instead.

Here's the code:

.my-pixiv-gallery { text-align: center; }
.my-pixiv-gallery .pixiv-embed-title { display: none; }
.my-pixiv-gallery .pixiv-embed-meta { display: none; }
.my-pixiv-gallery .pixiv=enbed { display: inline=block; }
<div class="my-pixiv-gallery">EMBED 1 EMBED 2 EMBED 3...</div>

For the uninitiated: when you use display: inline-block or display: inline to put divs side-by-side, they're treated like huge letters. This means that putting a space or new line in the code between a div and the other creates an actual space between them.

Spaced: <div>...</div> <div>...</div>
Together: <div>...</div><div>...</div>

Gallery Example

Async Pixiv Embeds or Defer

One last thing that's sort of important but kinda technical is how to make the embed script work asynchronously, by using the attributes async or defer. This because it loads faster this way.

By default, the script uses document.write to embed the images, which is basically the worst way to do anything ever. First off, if a browser encounters a scripts in the middle of the page, it can't render what comes after that script until the script is finished doing its scripty stuff.

This means, for example, that if your internet is slow or Pixiv is having bandwidth trouble and you want to read what's written at the bottom of the page, the comments for example, that stuff won't show up in the browser until the script finishes embedding. If you have embedded multiple images, that's multiple scripts, so the lag multiplies.

Worse yet, document.write can only be used when the page hasn't finished loading yet, and so you usually have to put the script in the spot you want it to write its embed code. It's a bit hard to move it to the bottom of the page and make it work. (although it's possible, because I have done it with the Amazon ads, that use document.write, but it's troublesome.)

All of this would make any developer go: fuck whoever programmed this piece document.writing bullshit!!!111

Fortunately, the Pixiv developers did include a way to let you embed without document.write and consequently asynchronously. (which seems to be undocumented, as one would expect, and can only be found by looking at the source code of the script and reading the header comments.)

Better Embed Code

The embed code that's on the Pixiv page is synchronous. You have to modify it a bit in order to make it work asynchronously.

First off, remove the attributes data-id, data-border and data-size from the <script> element. If the script sees it has those attributes, it will try using document.write which isn't what we want.

Create a div classed pixiv-embed and put the attributes in it.

Now, when the embed script finishes loading, it will search for divs classed pixiv-embed and use their attributes to add the embedded images.

Next you have to take your script element and put it at the end of the page so it doesn't force the page to pause loading. In this case, you may also use the attribute async to make it load asynchronously. But remember you have to put it at the end of the page otherwise it might not catch all the divs of the page.

Alternatively, you can use the attribute defer and put the script at the start of the page. With defer it loads asynchronously but only executes after the page has finished loading.

Note that in any case you should only have 1 <script> element. Even if you have 2 or more embeds, you don't need 2 <script> to make them all load using this asynchronous technique. In fact if you use 2 it will make them load twice, so watch out.

The code should go from:

<script src, id, size, border><noscript>blah blah blah</noscript>


<script src & defer="defer"><div class="pixiv-embed" id, size, border>put the noscript here, maybe?</div>

Code Example

<script defer="defer" src="" charset="utf-8"></script>
<div class="pixiv-embed" data-id="46118362_e92a647082372e6944a875cb4d51c9b4" data-size="small" data-border="off">
<noscript><p><a href=";illust_id=46118362" target="_blank">さばげぶっ!観始めました</a> by <a href="" target="_blank">さかき@妖精領域</a> on <a href="" target="_blank">pixiv</a></p></noscript>

Final Words

Well, that post was a bit off-topic, but I hope this will help somebody someday.

No comments:

Post a Comment

Leave your komento コメント in this posuto ポスト of this burogu ブログ with your questions about Japanese, doubts or whatever!