2

Hope all stack members are alright .I am able to fetch binary data of Product image using code

p_ids=self.env.context.get('active_ids')
produtc_templates = self.env['product.template']
for p_id in p_ids:
 binaryData = produtc_templates.search([('id', '=',p_id)]).image 
 data=base64.b64decode(binaryData)
        file="marketplaces/rakuten_ftp/static/imageToSave_"+str(p_id)+".png"
        with open(file, "wb") as imgFile:
            imgFile.write(data)

Above code is create files from binary Data But i am failed to apply condition on mimetype base.Because when i query ir_attachment table with Products id's it return me False.

for p_id in p_ids:
 attachments = self.env['ir.attachment']
 mimetype=attachments.search([('res_id','=',p_id)])

I am considering res_id as Product id .But odoo failed to find any record against that id.So if any body have idea that how i can get mimetype against my product id then please help me.

Hassan ALi
  • 1,313
  • 1
  • 23
  • 51
  • You can save image data to png, weather it was originally png or jpg `with open('a.png', "wb") as imgFile: imgFile.write(data)` it will work if data is image data (whatever png or jpg – Sami Apr 14 '18 at 18:20

2 Answers2

3

Your code looks good! But as per ir.attachement object, binary data stored in datas field. So, you can use that data to decode binary data to image file!!

Already tried below code into Odoo v11... & it's working as created new image file from binary data which is stored in datas field!

product_image = self.env['ir.attachment']
product_images = product_image.search([('id', 'in', p_ids)])
for rec in product_images:
    with open("imageToSave.jpg", "wb") as imgFile:
        imgFile.write(base64.b64decode(rec.datas))

You can also add the condition for mimetype as, p_ids can contains multiple ids, so taking only those ids which have mimetype of image/jpeg or image/png

EDIT #1

Below code snippet already checked with Odoo v11.0

import base64
from odoo.tools.mimetypes import guess_mimetype


p_ids = [16, 18, 11, 38, 39, 40]  # Taking random ids of product.template
produtc_templates = self.env['product.template']
for p_id in p_ids:
    binary_data = produtc_templates.search([('id', '=', p_id)]).image
    mimetype = guess_mimetype(base64.b64decode(binary_data))
    file_path = ""
    if mimetype == 'image/png':
        file_path = "/home/Downloads/" + str(p_id) + ".png"
    elif mimetype == 'image/jpeg':
        file_path = "/home/Downloads/" + str(p_id) + ".jpeg"

    if file_path:
        with open(file_path, "wb") as imgFile:
            imgFile.write(base64.b64decode(binary_data))
bud-e
  • 1,511
  • 1
  • 20
  • 31
  • Thanks for your help . But now i am failed to find me image at rakuten_ftp/static/imageToSave.png this location. – Hassan ALi Apr 10 '18 at 07:51
  • @HassanALi As per that code snippet, if we did not specify path then it'll be saved in the same directory of `odoo`. If you want that newly created file at different place then specify path..... `with open("/home/flash/Downloads/imageToSave.jpg", "wb") as imgFile:` with this that file will be created in the `Downloads` directory! – bud-e Apr 10 '18 at 08:35
  • How i can get mimetype Because that's how i am image = produtc_templates.search([('id', '=',p_id)]).image finding binary image but using same method i can find mimetype. – Hassan ALi Apr 12 '18 at 06:52
  • You can find `mimetype` field in `ir.attachment` object!! You can modify your domain like this... `product_images = product_image.search([('id', 'in', p_ids), '|', ('mimetype', '=', 'image/jpeg'), ('mimetype', '=', 'image/png')])` – bud-e Apr 12 '18 at 09:03
  • product_images = product_image.search([('id', 'in', p_ids) against id it return different records . and against res_id it return False . – Hassan ALi Apr 12 '18 at 10:31
  • Ohh, You already modified your question & I didn't see that!! I told you apply condition based on `mimetype` because before modification you are searching from `ir.attachment` object & in that any type of data(link, image, PDF, etc...) can be saved! – bud-e Apr 12 '18 at 11:38
  • But now after modification of question... I see that your are searching from `product.template` & in that object `widget='image'` is used in that image field! So, No need to re-apply that mimetype condition!! All image data already comes with mimetype of `jpeg`, `jpg`, `png` !! So, Just `product_images = product_image.search([('id', 'in', p_ids)])` will be fine!! No extra condition!! And also if your are trying to search that `p_ids` in `ir.attachement` then obviously its not going to work!! Because now `p_ids` are record of `product.template` not `ir.attachment`. – bud-e Apr 12 '18 at 11:38
  • sorry but i am not able to find mimetype from image data till.Because its not providing me binary data . So if you have idea how i can get mimetype from image data then please tell me . Thanks for your valuable time .Sir – Hassan ALi Apr 12 '18 at 12:26
  • guess_mimetype(values['datas'].decode('base64')) try this decode the datas field and give as parameter to guess mime type in _compute_mimetype method – Hari Apr 16 '18 at 07:32
  • @HassanALi Check with my Edited Answer!! – bud-e Apr 17 '18 at 06:35
  • Sorry I was busy at work .But your solution worked for me . Thanks for your time. – Hassan ALi Apr 21 '18 at 19:40
1

Product images aren't saved as instances/records of ir.attachment. OK, maybe that has changed, but i didn't find anything so fast.

What you can do, is using ir.attachment's method _compute_mimetype()

Following example wasn't tested:

def get_mimetype_of_product_image(self, product_id)
    product = self.env['product.product'].browse(product_id)
    mimetype = self.env['ir.attachment']._compute_mimetype(
        {'values': product.image})
    return mimetype
CZoellner
  • 13,553
  • 3
  • 25
  • 38