Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

the quality in PNG export is a bit pixelated #137

Open
kunaumadein opened this issue Jun 22, 2022 · 14 comments
Open

the quality in PNG export is a bit pixelated #137

kunaumadein opened this issue Jun 22, 2022 · 14 comments
Labels
bug:bug: Something isn't working

Comments

@kunaumadein
Copy link

Hello,

so I don't want to make it a bug report but I just have a question. When I export my graphic as PNG (with the dimensions 1200x627) my graphic looks a bit pixelated.

So my question would have been if you can also export with quality to JPG via mechanic.design or if the export of my graphic is in double size without having to set the width and the height.

Below is a screenshot of what my export looks like (beneath my export and above the my prototype).

CleanShot 2022-06-22 at 10 17 53@2x

Thanks in advance!

@kunaumadein kunaumadein added the bug:bug: Something isn't working label Jun 22, 2022
@munusshih
Copy link
Contributor

Can you describe what engine you're using? Is this p5?

@kunaumadein
Copy link
Author

Oh sorry about that bit I am using the react engine @munusshih

@munusshih
Copy link
Contributor

That's okay! Can you post your code here so we can better test it out and figure out the problem? Thanks!

@kunaumadein
Copy link
Author

kunaumadein commented Jun 23, 2022

yeah sure @munusshih

import React, { useEffect, useState } from "react";
import ImgBanner from './assets/banner.svg';
import ImgEBCLogo from './assets/ebc-logo.svg';
import "./styles.css";

export const handler = ({ inputs, mechanic }) => {
    const {
        dateTypeAndLocation,
        eventType,
        firstLine,
        secondLine,
        subTitel,
        sponsoredBy,
    } = inputs;

    const { topLogo, sponsorLogo } = inputs;
    
    /*
    const [topHref, setTopHref] = useState("");
    */
    const [bottomHref, setBottomHref] = useState("");

    const loadImageFromFileObject = (fileObject, stateSetter) => {
        const reader = new FileReader();
        reader.onload = () => {
            stateSetter(reader.result);
        };
        reader.readAsDataURL(fileObject);
    };

    useEffect(() => {
        if (topLogo) loadImageFromFileObject(topLogo, setTopHref);
        if (sponsorLogo) loadImageFromFileObject(sponsorLogo, setBottomHref);
    }, []);

    useEffect(() => {
        if ((!sponsorLogo && !bottomHref) || (bottomHref && sponsorLogo)) mechanic.done();
    }, [sponsorLogo, bottomHref]);

    useEffect(() => {
      if ((!sponsorLogo && !bottomHref) || (bottomHref && sponsorLogo)) mechanic.done();
  }, [sponsorLogo, bottomHref]);

    /*
 useEffect(() => {
  if ((topHref || bottomHref) && (!topLogo ||  topHref) && (!bottomLogo || bottomHref)) mechanic.done();
}, [topLogo, topHref, bottomLogo,  bottomHref]);
*/

return (
    <svg width={1200} height={627}>
      <favicon url="./assets/favicon.ico"/>
        <image href={ImgBanner} width={1200} height={627} />
        <image
          x={950}
          y={-10}
          width={200}
          height={200}
          href={ImgEBCLogo}
        >
        </image>

        <image
          x={200}
          y={447}
          width={230}
          height={230}
          href={bottomHref}
        >
        </image>
        {/* The text */}

        <text
          x={40}
          y={75}
          fill={'#ffffff'}
          textAnchor="start"
          fontWeight="regular"
          fontFamily="Garnett Regular"
          fontSize={30}
        >
          {dateTypeAndLocation}
        </text>

        <text
          x={40}
          y={125}
          fill={'#ffffff'}
          textAnchor="start"
          fontWeight="regular"
          fontFamily="Garnett Regular"
          fontSize={30}
        >
          {eventType}
        </text>
          <text
            x={40}
            y={300}
            fill={'#ffffff'}
            textAnchor="start"
            fontWeight="regular"
            fontFamily="Garnett Regular"
            fontSize={72}
          >
            {firstLine}
          </text>

        <text
          x={40}
          y={385}
          fill={'#ffffff'}
          textAnchor="start"
          fontWeight="regular"
          fontFamily="Garnett Regular"
          fontSize={72}
        >
          {secondLine}
        </text>

        <text
          x={40}
          y={575}
          fill={'#ffffff'}
          textAnchor="start"
          fontWeight="regular"
          fontFamily="Garnett Regular"
          fontSize={30}
        >
          {subTitel}
        </text>

        <text
          x={40}
          y={575}
          fill={'#ffffff'}
          textAnchor="start"
          fontWeight="regular"
          fontFamily="Garnett Regular"
          fontSize={20}
        >
          {sponsoredBy}
        </text>
    </svg>
  );
};

export const inputs = {
  dateTypeAndLocation: {
    type: "text",
    default: "Monday March 21st: From 11.00-11.45",
  },
  eventType: {
    type: "text",
    default: "Webinar",
  },
  firstLine: {
    type: "text",
    default: "Guidelines for Blockchain",
  },
  secondLine: {
    type: "text",
    default: "and DLT Governance",
  },
  subTitel: {
    type: "text",
    default: "- the new standard explained",
  },
  sponsoredBy: {
    type: "text",
    default: "",
  },
  sponsorLogo: { 
    type: "image",
    multiple: false,
  },
};

//Voreinstellungen/Presets
export const presets = {
  LinkedIn: {
    width: 1200,
    height: 627,
  }
};

export const settings = {
  engine: require("@mechanic-design/engine-react"),
  showMultipleExports: true,
  hideScaleToFit: true,
  hideGenerate: true,
  optimize: false,
  hideFeedback: true
};

but i didn't defined any export options because it is handled via the various react dependencies

@runemadsen
Copy link
Contributor

@kunaumadein Which browser are you using to run the design tool?

@kunaumadein
Copy link
Author

@runemadsen i am using chrome

@runemadsen
Copy link
Contributor

Thanks @kunaumadein! Would it be possible for you to upload the entire code in a GitHub repository, so we can see what's going on? Also, since this is the React engine, does the SVG output look ok?

@kunaumadein
Copy link
Author

The SVG output looks good but i wanted to provide my client that he only uses PNG for various kinds of socia media platforms. And i just uploaded my whole project @runemadsen
https://github.com/kunaumadein/kunaumadein.github.io

@kunaumadein
Copy link
Author

Hello @runemadsen
I would like to ask if there is any news regarding the export.

@runemadsen
Copy link
Contributor

runemadsen commented Jul 6, 2022

I just looked into this, and it's a problem related to how we convert SVG to PNG in @mechanic-design/core. This thread (https://stackoverflow.com/questions/41763580/svg-rendered-into-canvas-blurred-on-retina-display) explains the problem and offers a solution that we can use to fix it. We'll make sure to add this as a thing to fix. Until then, you can use one of the canvas-based engines (such as engine-canvas or engine-p5) if you're only interested in PNG output.

@kunaumadein
Copy link
Author

Ah ok i see @runemadsen thx for the answer!
You mentioned a thread above is there maybe a link or so?

@runemadsen
Copy link
Contributor

Sorry, just updated my comment. Thanks for posting all of this. It's super helpful as we keep developing the framework, and we'll try to get this fixed as soon as we can.

@kunaumadein
Copy link
Author

Thanks for the support and am very curious about the future updates!
I would say you can close this issue.

@lucasdinonolte
Copy link
Contributor

Ok, so we've done some testing and research and found the cause of the issue.

We use Canvas under the hood to convert the SVG to a PNG. Canvas by default treats pixel values as being pixel values at an old monitor's density (72dpi), so when exporting the preview SVG (which in theory has an infinitely high resolution) gets compressed to 72dpi. So technically this is "expected behavior"—but very annoying behavior.

This is why we're currently exploring possibilities of adding the option to select the export pixel density to Mechanic. A promising-looking work in progress of this is in this PR: #144 This would then work similar to how you'd export a PNG from Illustrator, allowing you to choose if you want the image to be at 1x, 2x, 3x and so on.

In the meantime a work-around could be to just double all sizes so you export your PNG at double the size. When scaled down to 50% this will yield a retina-compatible PNG. At least that's how I've exported Retina-ready assets from Mechanic in the past.

Again, thanks so much for opening this issue 😊 We'll keep updating this issue with progress and release schedule on the export density feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug:bug: Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants