SurveyLoopr
Tips & Tricks
13 min read

Images in XLSForm Questions and Choices: ODK, Kobo

Mehrab Ali
Mehrab AliPublished November 7, 2026

To add a picture to an XLSForm question, type its file name, such as muac_tape.png, in the image column of that row; to give each answer option its own picture, add an image column to the choices sheet with one file name per choice. ODK Collect, KoboToolbox and SurveyCTO show the picture with the question or the option, and every example below compiles with pyxform and ODK Validate, the same check ODK Central runs when you upload a form.

Download example form (.xlsx)All seven examples in one XLSForm, one group each. Tested with pyxform and ODK Validate; free to reuse under CC BY 4.0. Add your own image files before you upload it.Download

What is the syntax for an image in a question?

Add a column called image to the survey sheet and type the file name in the row of the question that needs the picture:

typenamelabelimage
integermuac_mmRead the MUAC tape at the middle of the upper arm and enter the value in mm.muac_tape.png
select_one yes_nooedemaPress both feet with your thumbs for 3 seconds. Does a dent stay on both feet?oedema_check.png
surveychoicessettings
list_namenamelabel
yes_no1Yes
yes_no0No
surveychoicessettings

The picture shows below the question text, and the enumerator answers as usual. Three rules decide whether it appears:

  • The cell holds a file name, not a path. Type muac_tape.png, never C:\Pictures\muac_tape.png or a web address.
  • The name must match the uploaded file exactly, case included. MUAC_Tape.PNG is a different file.
  • The column can also be called media::image. Both spellings compile to the same form.

The image column works on any row type, notes included. A note with a picture and no question is how you show a logo or an instruction card; see adding a logo to an XLSForm.

How do I add pictures to answer choices?

Add an image column to the choices sheet. Each choice row gets its own file name, and a choice with an empty cell simply shows no picture:

typenamelabel
select_one toilet_typetoiletWhat kind of toilet facility do members of this household usually use?
surveychoicessettings
list_namenamelabelimage
toilet_type1Flush or pour-flush toiletflush_toilet.png
toilet_type2Pit latrine with slabpit_slab.png
toilet_type3Pit latrine without slab or open pitpit_open.png
toilet_type4Composting toiletcomposting.png
toilet_type5Bucket or hanging toiletbucket.png
toilet_type6No facility (bush or field)no_facility.png
toilet_type-96Other
surveychoicessettings

Pictures help most when the words are not enough: toilet and water source types, food items, crop diseases, livestock breeds or stages of a building. The respondent can point at the right picture instead of guessing what "pit latrine with slab" means.

Warning:

Keep a text label on every choice, even when you only want the picture to show. A choice with an image and an empty label still compiles, but pyxform warns On the 'choices' sheet, the 'label' value is invalid. Choices should have a label. The label is also what you read in the exported data and in screen readers.

How do I show the choice pictures as a grid?

A long list of pictures, one under the other, makes the enumerator scroll. The columns-2 appearance lays the choices out in two columns, and no-buttons drops the radio buttons or check boxes so each picture becomes the button:

typenamelabelappearance
select_multiple food_groupfoods_eatenWhich of these foods did the child eat yesterday? Tap every picture that applies.columns-2 no-buttons
surveychoicessettings
list_namenamelabelimage
food_group1Grains roots and tubersgrains.png
food_group2Beans peas and lentilspulses.png
food_group3Milk and dairydairy.png
food_group4Meat fish and poultrymeat_fish.png
food_group5Eggseggs.png
food_group6Dark green leafy vegetablesleafy_greens.png
food_group7Other fruits and vegetablesfruit_veg.png
surveychoicessettings

How the layouts differ in ODK Collect:

AppearanceWhat the enumerator sees
NoneOne picture per row, with its label and a radio button or check box
columns-2, columns-3 and so on (columns-n)That many columns, each with label and button
columnsAs many columns as the screen width allows
columns-packAs many choices per line as fit, in uneven columns
no-buttonsOnly the pictures, without the label or the button; add a columns appearance for a grid

The ODK documentation notes that more than two columns can feel crowded on a small phone screen, and small pictures are easy to mix up. Other select appearances, such as minimal and likert, are in the XLSForm appearance column guide.

How do I let the enumerator zoom into a picture?

Add a big-image column with a larger, more detailed copy. The small file from the image column shows in the form; tapping it opens the big one full screen, where the enumerator can pan and zoom:

typenamelabelimagebig-image
notecatchment_mapYour enumeration area is marked in red. Tap the map to make it bigger.ea_map_small.jpgea_map_large.jpg
select_one yes_noin_eaIs this household inside the area marked in red?
surveychoicessettings

big-image also works on the choices sheet, for example a close-up of a leaf disease next to each choice. It does not work with the no-buttons appearance: those choices show no media buttons, so there is nothing to tap.

How do I use a different picture for each language?

When the picture holds text, such as a show card with written answers, name an image column per language, the same way as the label columns. The picture changes when the enumerator switches language:

typenamelabel::English (en)label::French (fr)image::English (en)image::French (fr)
noteladder_cardShow the respondent the card and ask them to point at their answer.Montrez la carte à la personne interrogée et demandez-lui de montrer sa réponse.ladder_en.pngladder_fr.png
integerladder_stepWhich step of the ladder are you on today? (0 to 10)Sur quelle marche de l'échelle êtes-vous aujourd'hui ? (0 à 10)
surveychoicessettings

On the choices sheet, use the same pattern: label::English (en), label::French (fr), image::English (en) and image::French (fr). If the labels have languages but the image column does not, the form still compiles, but pyxform warns Language 'English (en)' is missing the choices image column. Name both columns the same way. A picture without words still needs an image:: column per language; put the same file name in each. Setting up the language columns is covered in adding languages to an ODK form.

Can I add audio or video instead of a picture?

Yes. The audio and video columns work like image, on the survey sheet and on the choices sheet, and a row can have all three. Collect shows a play button next to the text:

typenamelabelaudiovideo
noteconsent_audioPlay the consent statement to the respondent in their language.consent_statement.mp3
noteors_demoWatch how to prepare the oral rehydration solution before you show the mother.ors_demo.mp4
select_one yes_noconsentDoes the respondent agree to take part?
surveychoicessettings

Audio helps respondents who cannot read: they can listen to each option instead. Keep recordings short and files small, because every phone downloads them with the form.

What if the image names are only in a CSV file?

ODK Central asks for the files that the XLSForm names. If image names live only inside an attached CSV, for example a product list, Central does not list them and you cannot attach them. The workaround the ODK team suggests in its forum is a hidden question whose choices name every image:

typenamelabelrelevant
select_one product_photosmedia_listProduct photos used by the price listfalse()
textshop_idEnter the shop ID from the listing sheet.
surveychoicessettings
list_namenamelabelimage
product_photos1Ricerice_5kg.jpg
product_photos2Lentilslentils_1kg.jpg
product_photos3Cooking oiloil_1l.jpg
surveychoicessettings

relevant is false(), so the question never shows and stays empty in the data, but Central now asks for the three files and Collect downloads them with the form.

What size and format should the images be?

Use PNG or JPG, and keep each file small: every phone downloads every image with the form, often over mobile data. The ODK documentation's advice for images in forms:

  • Make all images the same size, for example 300 x 300 pixels.
  • Keep the background simple, with even space around the subject.
  • Use icons from one library, in one style, so no picture stands out more than the others.
  • Test in light and dark mode. A transparent PNG with dark lines can disappear on a dark screen.
Note:

Avoid SVG files in the image column. In ODK forum tests, SVG pictures could not be zoomed in Collect and opened badly in some phones' default viewers. SVG is right only for the image-map appearance, where the enumerator taps regions of the picture.

Common mistakes with images in XLSForm

Most of these compile without an error. They show up on the phone or in ODK Central:

You wroteWrite insteadWhat you will see
A choice with an image and no labelKeep the label; no-buttons hides it on screenOn the 'choices' sheet, the 'label' value is invalid. Choices should have a label.
label::English (en) with a plain image column on choicesimage::English (en) next to label::English (en)Language 'English (en)' is missing the choices image column.
image::English (en) with a plain label column on choicesName the label and image columns the same wayLanguage 'English (en)' is missing the choices label column.
A column called images or pictureimage or media::imageNo error and no pictures; the column is ignored
Pit_Slab.PNG in the cell, pit_slab.png uploadedThe exact file name, case includedODK Central lists the file as still expected
One choice image not uploadedAttach every file before publishingCollect may show another choice's picture in that place
big-image with no-buttonsDrop no-buttons, or drop big-imageNo error; the large image cannot be opened
A PNG with the image-map appearanceAn SVG with an id on each tappable regionNo error at upload; nothing to tap on the phone

For other messages, see common XLSForm errors, or paste the form into the free XLSForm validator.

Does this work the same in ODK, KoboToolbox and SurveyCTO?

The idea is the same everywhere: a file name in a media column, and the file uploaded with the form. The column names and the upload step differ:

PlatformMedia columnsWhere you upload the files
ODK Central (Collect and Web Forms)image or media::image, big-image, audio, videoAttach them to the form draft before publishing
KoboToolbox (KoboCollect and web forms)image or media::image, audio, videoProject Settings > Media, then redeploy
SurveyCTOmedia:image, plus the audio and video columns in its templateAttach them with the form definition

SurveyCTO's own form template spells the columns with a single colon. ODK Web Forms has added media support in stages, so open the web form preview as well as Collect before fieldwork. In KoboToolbox, if a picture shows in the preview but not in the deployed form, first check that the file under Settings > Media has exactly the name in the cell.

When are pictures worth adding?

Add them where they change the answer: items that have no local name, categories respondents confuse, and questions for people who cannot read. A WASH survey that shows a photo of each toilet type gets fewer "other, specify" answers than one that only lists the names. Leave them out of questions the words already answer, because each picture adds download size and screen space.

Tip:

You can ask for it in plain language instead: "add a picture to each toilet type choice and show them as a two-column grid". LooprAI writes the image column and the appearance and compiles the form with pyxform before anything is saved; then attach the image files in the form's media.

Build my first form free

Next: XLSForm appearance column →

Frequently Asked Questions

How do I add an image to a question in ODK?

Add an image column to the survey sheet and type the file name, such as muac_tape.png, in the question's row. Upload the XLSForm to ODK Central, attach the image to the draft when Central lists it as expected, then publish.

How do I put images on select_one choices?

Add an image column to the choices sheet and type one file name in each choice row. Keep the text label too. Upload every image with the form; a choice whose image cell is empty shows only its label.

How do I show only pictures without radio buttons?

Use the no-buttons appearance on the select_one or select_multiple question. The choices then show only their images, and tapping a picture selects it. Add columns-2 as well, as in columns-2 no-buttons, to lay the pictures out in a grid.

Why are my choice images not showing in KoboToolbox?

Usually the file names do not match. Check that each name in the image column matches a file under the project's Settings > Media exactly, case included, and that you redeployed after uploading. Also check the column is called image or media::image.

Can the enumerator zoom into an image?

Yes. Add a big-image column with a larger copy of the picture. Collect shows the small image from the image column, and tapping it opens the big one full screen with pan and zoom. It does not work with the no-buttons appearance.

Do I need a separate image for each language?

Only when the picture holds text, such as a show card. Then add image::English (en) and image::French (fr) columns next to the matching label columns. A picture without words can use the same file name in every language's image column.

No Credit Card Required

Build the form first. Add hosting when you need it.

Start free with LooprAI, then deploy a managed ODK Central server or run DataSnap checks when your project is ready.

Automation handles the mechanical work.

Researchers decide what the evidence means.