7

I'm working with a Magento 2 project that need to upload image using a POST endpoint

How can I send image content to this endpoint?

Or I have to base64 the image at client side and send the base64 content to POST endpoint?

Thank you very much.

10

If you want to upload product image using rest api. You need to pass below parameters in your request.

Your media upload url - http://127.0.0.1/megento2/index.php/rest/V1/products/{sku}/media.

Method name - Post

Below are the body parameters :

[
  {
    "id": 0,
    "media_type": "test",
    "label": "test",
    "position": 0,
    "disabled": true,
    "types": [
      "thumbnail"
    ],
    "file": "test.png",
    "content": {
      "base64_encoded_data": "Here i have passed base64_encoded data of image",
      "type": "file/png",
      "name": "test.png"
    },
    }
  }
]

Note : Make sure you pass base64_encoded_data of image.

4
  • Hi Manthan Dave, so basically Magento 2 API does not support file input, right? I worked with Laravel API, and they support file input, wonder why Magento 2 doesn't do this? Jun 23 '17 at 9:56
  • 1
    Yes Bang on @piavgh - Magento 2 rest api for media upload its not supporting file input , you must need to pass base64 encoded image. or you can create your custom observer for that . Jun 23 '17 at 10:19
  • Thank you Manthan. Can you please tell me more about the custom observer approach? I didn't understand it clearly. I think that whether we use observer or not, we still have to get the file from api, right? But this is what Magento 2 API doesn't support. Jun 23 '17 at 15:46
  • Well better to do one thing , send base64_encoded image and decode it where you needed file format. using base64_decode and then do put_file_contents with image name it will create new image for you Jun 23 '17 at 16:14
1

By default it is necessary to send the image encoded in base 64.

For a project, a client asked me to prevent the images from being sent encoded through the API to reduce the transmission time when the products of the catalog were updated. As it is obviously not possible to send the image files through the API the solution was a plugin that modifies the behavior of magento 2 to search the image files in the folder "pub/media/import"

https://github.com/olivertar/m2_api_product_images

1
  • This thing is just GOLD! Need to do a Pull Request tho, to change the ['data'] thing which was suggested in the issue by "cad-software" :) Nov 24 '20 at 13:13
1

Pass files as below in API payload

{
    "files": [
        {
            "type": "image/jpeg",
            "name": "test.png",
            "base64_encoded_data": "your base64 encoded image content"
        }
    ]
}

Inside your Model class

<?php

namespace UrVendor\UrModule\Model;

use Magento\Framework\Api\ImageProcessorInterface;
use Magento\Framework\Api\Data\ImageContentInterfaceFactory;

class UrClassName implements UrClassNameInterface
{
    private $imageProcessor;
    private $imageContentFactory;

    public function __construct(
        .....
        ImageProcessorInterface $imageProcessor,
        ImageContentInterfaceFactory $imageContentFactory
    ) {
        .....
        $this->imageProcessor = $imageProcessor;
        $this->imageContentFactory = $imageContentFactory;
    }
    
    public function urApiFunction($files) {
        if (count($files) > 0) {
            $destinationFolder = 'test';
            foreach ($files as $file) {
                $imageContent = $this->imageContentFactory->create();
                $imageContent->setBase64EncodedData($file['base64_encoded_data']);
                $imageContent->setType($file['type']);
                $imageContent->setName($file['name']);
                $filename = $this->imageProcessor->processImageContent($destinationFolder, $imageContent);
            }
        }
    
    }
}
0

To upload image you can use jquery fileupload. Here is example

view/frontend/layout/default.xml (layout you need)

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
        <css media="all" src="jquery/fileUploader/css/jquery.fileupload-ui.css"/>
    </head>
</page>

You could create widget or just use require js

$wrapper.find('input[type=file]').fileupload({
    dataType: 'json',
    formData: {
       'form_key': window.FORM_KEY
    },
    limitMultiFileUploads: 1,
    acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
    done: function (e, data) {
    }
});

More information here https://github.com/blueimp/jQuery-File-Upload

and your Controller

<?php
namespace Vendor\Module\Controller;

use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\Framework\UrlInterface;

class Upload extends \Magento\Framework\App\Action\Action
{
    /**
     * @var \Magento\Framework\Controller\Result\JsonFactory
     */
    protected $resultJsonFactory;

    /**
     * @var \Magento\MediaStorage\Model\File\UploaderFactory
     */
    protected $uploaderFactory;

    /**
     * @var \Magento\Framework\Filesystem\Directory\Write
     */
    protected $mediaDirectoryWrite;

    /**
     * @param \Magento\Framework\App\Action\Context $context
     * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
     * @param \Magento\Framework\Filesystem $filesystem
     * @param \Magento\MediaStorage\Model\File\UploaderFactory $uploaderFactory
     */
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
        \Magento\Framework\Filesystem $filesystem,
        \Magento\MediaStorage\Model\File\UploaderFactory $uploaderFactory
    ) {
        parent::__construct($context);

        $this->resultJsonFactory = $resultJsonFactory;
        $this->uploaderFactory = $uploaderFactory;
        $this->mediaDirectoryWrite = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
    }

    /**
     * @return \Magento\Framework\Controller\Result\JsonFactory
     */
    public function execute()
    {
        if (!$this->mediaDirectoryWrite->isWritable('MEDIA_PATH')) {
            $this->mediaDirectoryWrite->create('MEDIA_PATH');
        }

        $resultJson = $this->resultJsonFactory->create();
        try {
            $targetPath = $this->mediaDirectoryWrite->getAbsolutePath('MEDIA_PATH');
            $uploader = $this->uploaderFactory->create([
                'fileId' => 'file'
            ]);
            $uploader->setAllowedExtensions(['gif', 'png', 'jpg', 'jpeg']);
            $uploader->setAllowRenameFiles(true);
            $uploader->setFilesDispersion(true);
            $result = $uploader->save($targetPath);

            $result['file'] = ltrim($result['file'], '/');
            $result['url'] = $this->_url->getBaseUrl(['_type' => UrlInterface::URL_TYPE_MEDIA])
                . 'MEDIA_PATH'
                . '/'
                . $result['file'];
        } catch (\Exception $e) {
            $result = ['error' => $e->getMessage(), 'errorcode' => $e->getCode()];
        }

        return $resultJson->setData($result);
    }
}
6
  • Thank Nicholas. But I need to send image to REST API, not controller as you suggested. Jun 22 '17 at 2:56
  • Look at devdocs.magento.com/swagger/index_20.html how POST was implemented in catalogProductRepositoryV1 method. In this way you should send base64encoded data. Jun 22 '17 at 3:10
  • You mean this part "content": { "base64EncodedData": "string", "type": "string", "name": "string" }, right? Jun 22 '17 at 3:12
  • yes, in mediaGalleryEntries Jun 22 '17 at 3:13
  • I strongly disagree with your statement. Using a custom controller instead of the provided API is not recommendable. Why would any webserver disallow a JSON post but allow a file upload?
    – ooxi
    Jun 25 '17 at 19:25
0

I did what Manthan Dave has sent, but when I do it via Magento API,looks like it makes a copy and so I always get an extra image. IS there anything I have to do? (I dont have enough reputation to comment, sorry!)

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.