I tried to get it well formatted but I won it

I hope the question is understood I'm using the google form which allows you to do multiple choice tests, if they were language no problem, the problem they are math exercises and the only way they look decent is by inserting pictures both in the problem header with in the alternatives, but cutting each picture of each problem means 6 cuts and if they are 30 questions is a long time. The idea is to have "x" amount of images in a directory and that mathematician import them one by one P01.png,P02.png.... and identify the black color of the writing and cut the image in 6 parts if you can of the same size of the writing and name them of the form p01. png, p01_a.png,p01_b.png,p01_c.png ,p01_d.png,p01_e.png,p02.png, p02_a.png,p02_b.png,p02_c.png ,p02_d.png,p02_e.png....... and save them in a subdirectory "y" inside "x Someone could help me please

Image from P01.png Image from P01.png

 Image from p01.png Image from p01.png

Image from p01_a.png Image from p01_a.png

  Image from p01_b.png Image from p01_b.png

Image from p01_c.png Image from p01_c.png]

Image from p01_d.png Image from p01_d.png

Image from p01_d.png Image from p01_e.png


1 Answer 1


Update 2

This is a better implementation of the parts function that does not assume that the spacings are the same. It finds groups of rows in the image that are not composed of entirely white pixels and splits by those groups.


parts[image_] := Module[{width, height, imageData},
  {width, height} = ImageDimensions@image;
  imageData = ColorConvert[image, "Grayscale"] // ImageData;

  imageData // 
  Position[#, ConstantArray[1., width]] & //       
  Flatten //
  Complement[Range[height], #] & //     
  Split[#, (#2 - #1 == 1 &)] & //
  Map[MinMax] //   
  Map[Take[imageData, #] & /* Image]]

The rest of the code in the update below is unchanged.


To process a directory of images

importPath = "path to import directory";
exportPath = "path to export directory"; (* Must already exist *)

ClearAll[parts, exporter];

parts[image_] := ImagePartition[image, Scaled[{1, 1/6}]] // Flatten

exporter[baseName_, parts_] := 
  Export[baseName <> "_" <> #1 <> ".png", #2] &, {{"a", "b", "c", "d", "e", "f"}, parts}]

importedImages = AssociationMap[Import, FileNames["*.png", importPath]];

importedImages // 
  KeyValueMap[exporter[FileNameJoin[{exportPath, FileBaseName@#1}], parts[#2]] &];

If the spacing between the text is the same then you can partition it

img = Import["~/Downloads/21ttc.png"];
parts = ImagePartition[img, Scaled[{1, 1/6}]] // Flatten

enter image description here

Each image in the list can be exported to a different file.

MapThread[Export["P01_" <> #1 <> ".png", #2] &, {{"a", "b", "c", "d", "e", "f"}, parts}]
  • 1
    $\begingroup$ thanks what you expose serves me because they are at the same space,you could modify the code to do it importing all the images from a directory "x" dothe process and then export them to a directory "y" , n this code, MapThread[Export["P01_" <> #1 <> ".png", #2] &, {{"a", "b", "c", "d", "e", "f"}, parts}] P01_should be increased successively. $\endgroup$ Oct 9, 2020 at 4:02
  • $\begingroup$ @juanmuñoz A couple of questions so I can update the answer correctly. In directory x do all of the files have the .png extension? For the export filename, rather than P I suggest using <import_filename>_<alphabet> that way it is easy to associate an input file with its parts. Is that OK? $\endgroup$ Oct 9, 2020 at 13:21
  • $\begingroup$ So for the example above, the export files would be 21ttc_a.png, 21ttc_b.png, etc. $\endgroup$ Oct 9, 2020 at 13:27
  • $\begingroup$ @ Rohit Namjoshiin the directory "x" all the files have extension .pngse call P01.png ,P02.png ....... referring to the questions , as for the export to the directory "y" it would be important to differentiate the question from the alternatives, but what you do can be useful and any doubt I ask you , and thanks for your time $\endgroup$ Oct 9, 2020 at 14:54
  • 1
    $\begingroup$ Here is the function I used to do that. Should be easy to modify the code to run it and export to wherever you want. Let me know if you have any problems doing that. partsMarked[image_] := ImagePartition[image, Scaled[{1, 1/6}]] // ImageAssemble[#, Spacings -> 1, Background -> Red] & $\endgroup$ Oct 10, 2020 at 1:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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