Hi guys,
In this tutorial I will learn you how to create a new field that saves images, how to upload them correctly in your database and how to automatically resize them. With this demo you’ll learn how to instantly (automatically) resize uploaded images.
Tip:view my sample module here.
1. Create new fields
The first step is to create a new model and the new fields. For this demo I will create a clean, new table, but you could just simply add fields to an existing model.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
class upload_images(osv.osv): _name = 'upload_images.tutorial' _description = 'Tutorial image uploading' _columns = { 'name': fields.char('Name', required=True, translate=True), 'image': fields.binary("Image", help="This field holds the image used as image for our customers, limited to 1024x1024px."), 'image_medium': fields.function(_get_image, fnct_inv=_set_image, string="Image (auto-resized to 128x128):", type="binary", multi="_get_image", store={ 'upload_images.tutorial': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10), },help="Medium-sized image of the category. It is automatically "\ "resized as a 128x128px image, with aspect ratio preserved. "\ "Use this field in form views or some kanban views."), 'image_small': fields.function(_get_image, fnct_inv=_set_image, string="Image (auto-resized to 64x64):", type="binary", multi="_get_image", store={ 'upload_images.tutorial': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10), }, help="Small-sized image of the category. It is automatically "\ "resized as a 64x64px image, with aspect ratio preserved. "\ "Use this field anywhere a small image is required."), } |
As you can see I will create 4 fields. One to fill in a name and three fields of the type binary, which will be used to upload the images on. Every image field calls a field.function, which will then automatically resize the images:
1 2 3 4 5 6 7 8 |
def _get_image(self, cr, uid, ids, name, args, context=None): result = dict.fromkeys(ids, False) for obj in self.browse(cr, uid, ids, context=context): result[obj.id] = tools.image_get_resized_images(obj.image) return result def _set_image(self, cr, uid, id, name, value, args, context=None): return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context) |
So, what exactly does this do? The function get_image will find the correct image and returns it. Then the second function goes off, named _set_image. This function will call a pre-built function from Odoo to automatically resize the image.
2. Showing the new fields
Now that the model and fields are done they should also be showed. In my sample I will create a new menu item named ‘Images’ in the sales module, but you could just leave this out or place it anywhere else.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<record id="action_upload_images" model="ir.actions.act_window"> <field name="name">Images</field> <field name="type">ir.actions.act_window</field> <field name="res_model">upload_images.tutorial</field> <field name="view_type">form</field> <field name="view_id" ref=""/> <field name="view_mode">tree,form</field> </record> <menuitem id="menu_our_customers" action="action_upload_images" parent="base.menu_sales" sequence="14"/> <record id="view_images_form" model="ir.ui.view"> <field name="name">upload_images.tutorial.form</field> <field name="model">upload_images.tutorial</field> <field name="arch" type="xml"> <form string="Our images"> <group> <field name="name"/> <field name="image_medium"/> <field name="image_small"/> </group> </form> </field> </record> |
This will create a new menu item with the name ‘Images’, which is triggered by the action action_upload_images when the user clicks on it. The third record, view_images_form will show the fields and gives us the ability to visualise it as we want. Result:
3. Printing the images on a report
Now that the images can be saved and resized you should also be able to print them in your report!
Printing an image in a report is really easy:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<table> <tr> <td style="width:33% !important;"> Full size:<br/> <span t-field="o.image" t-field-options="{"widget": "image"}"/> </td> <td style="width:33% !important;"> 128x128:<br/> <span t-field="o.image_medium" t-field-options="{"widget": "image"}"/> </td> <td style="width:33% !important;"> 64x64:<br/> <span t-field="o.image_small" t-field-options="{"widget": "image"}"/> </td> <td style="width:33% !important;"> Name:<br/> <span t-field="o.name"/> </td> </tr> </table> |
This code will print the images out in the original format, in the 128x128px size and in 64x64px size. You simply need to call the image widget and you can print them out. When you’d print the report you would get something like this:
Tip: This whole tutorial is written in the Odoo V7 API. This is because Odoo 8 does not have fields.function and would complicate the task. If you’d really want it in Odoo 8 API you should have a look at computed fields.
Tip #2: You could also create an on_change event which then fills up different fields with different sizes of the images. This however would fill up the database much faster and is the reason why this is not in this tutorial.
I need this module will you please share the code regarding this module .The link you provided above was not fount in Github.Thanks
Hi geetha,
You can find it here: https://github.com/Yenthe666/Odoo_Samples/tree/master/upload_images
Thank you.
No problem, best of luck!
Hi, Yenthe, do you have idea how i can do this but in odoo 9? i need create a module where the user choice a image to upload and then print the image in the report (quotation).
Thank you 🙂
Hi Carlos,
Just create a binary field. The user can upload his image here and then you can print it in a report with a QWeb statement (see https://www.odoo.com/nl_NL/forum/help-1/question/how-to-get-images-from-db-on-qweb-report-odoo-8-70798 for example)
Hi, good post!!! congrats. Is possible defina a size diferent to 128×128 or 64×64? I tried with image_resize_image_big(value, size=(800, 600))
But nothing happened, the Method set 128×128 and 64×64
Hi Marcel,
Thanks a lot! By default you cannot change the sizes from 128×128 or 64x64x, they’re predefined by Odoo so you would either need to override it or create a new fileformat for this.
Thanks a lot man. So far two of your posts (this one and the “states widget” one) have really helped me. Keep updating them and thanks once again!
Hi Arnold,
Happy to hear they’ve really helped you, thanks a lot for the great feedback!
Hi Great Post
but i have a question, i have read that to improve performance we should not store images or files in database , but in filestore
do you know something about
Hi Franco,
Your performance will indeed be infected if you store images in the database. This has to do with the filestore parameter in Odoo though, if you Google around there are loads of topics about this.