## Fit an image within a Rectangle [] in Graphics

7

1

Based on the following Code (yet the white text in the image is added with PPT), I would like to have an image fit within one of the rectangle.

For Example the image from there :

2 main problem :

Although I know about Texture[], I have not been able to use it in my rectangle, nor drawing the correct polygon, or the correct vertex coordinates.

The image might not be of the same ratio, so I would like to crop it accordingly. I have not been able to yet without deforming the image.

My Ideal OutPut below :

c0 = {RGBColor[23/85, 29/255, 142/255], RGBColor[244/255, 1, 59/255],
RGBColor[1, 0, 32/85], RGBColor[18/85, 72/85, 197/255]}

Graphics[{EdgeForm[Thickness[.005]], White,
Rectangle[{0, 0}, {160, 90}], Black, Opacity[.7],
Rectangle[{0, 0}, {80, 63}], White, Opacity[1],
Rectangle[{80, 0}, {160, 63}], Opacity[1],
Flatten@({Flatten@(Table[
RandomChoice[{GrayLevel[.15], c0[[#]]}], {3}] & /@
Range[2, 4, 1]),
Function[{Xs, Ys},
Rectangle[{Xs, Ys}, {Xs + 16, Ys + 9}]], {Flatten@
Table[Range[0, 32, 16], {3}],
Flatten@(Table[#, {3}] & /@
Range[63, 81, 9])}]}\[Transpose])},
Method -> {"ShrinkWrap" -> True}, ImageSize -> 500]


7

What about this to create the textured rectangle. Here, pic is the picture you want to use for the Texture and ll and ur are the lower left and upper right corners of the box.

rec[ll_, ur_, pic_] := Module[{crop, boxrat},
boxrat = #2/#1 & @@ MapThread[Abs[#2 - #1] &, {ll, ur}];
crop = ImageCrop[pic, Transpose[{ ImageDimensions[pic]}],
AspectRatio -> boxrat];

{Texture[ImageData[crop]],
Polygon[Tuples[Sort /@ Transpose[{ll, ur}]][[{1, 2, 4, 3}]],
VertexTextureCoordinates -> Tuples[{0, 1}, 2][[{1, 2, 4, 3}]]]}]


For your example you would get

pic = Import[

Graphics[{EdgeForm[Thickness[.005]], White,
Rectangle[{0, 0}, {160, 90}], Black, Opacity[.7],
Rectangle[{0, 0}, {80, 63}], White, Opacity[1],

rec[{80, 0}, {160, 63}, pic], Opacity[1],

Flatten@({Flatten@(Table[
RandomChoice[{GrayLevel[.15], c0[[#]]}], {3}] & /@ Range[2, 4, 1]),
Function[{Xs, Ys},
Rectangle[{Xs, Ys}, {Xs + 16, Ys + 9}]], {Flatten@
Table[Range[0, 32, 16], {3}],
Flatten@(Table[#, {3}] & /@
Range[63, 81, 9])}]}\[Transpose])},
Method -> {"ShrinkWrap" -> True}, ImageSize -> 500]


which produces

Edit

Instead of cropping the image first and using that as the texture you can also play around with the settings for VertexTextureCoordinates. For example you could also do

rec2[ll_, ur_, pic_, f_:.5] :=
Module[{boxrat, picrat},
picrat = #2/#1 & @@ ImageDimensions[pic];
boxrat = #2/#1 & @@ MapThread[Abs[#2 - #1] &, {ll, ur}];
{Texture[ImageData[pic]],
Polygon[Tuples[Sort /@ Transpose[{ll, ur}]][[{1, 2, 4, 3}]],
VertexTextureCoordinates ->
Tuples[{
{f Max[0, 1 - picrat/boxrat], 1 - (1-f) Max[0, 1- picrat/boxrat]},
{f Max[0, 1 - boxrat/picrat], 1 - (1-f) Max[0, 1- boxrat/picrat]}}]
[[{1, 2, 4, 3}]]]}]


I've added an extra argument f which indicates which indicates how much of the left or right of the image should be cropped. For example a setting of 0 would indicate that all cropping should be from the right side of the image (or the top depending on the aspect ration of the image). When f==0.5 equal parts are cropped from the left and right sides and when f==1 the image is only cropped on the left side (or bottom).

Edit 2

It looks like Texture isn't playing nicely with Inset used in kguler's answer to your previous. To get the text and the image in the same picture you could do something like this instead

rec[ll_, ur_, pic_] := Module[{crop, boxrat},
boxrat = #2/#1 & @@ MapThread[Abs[#2 - #1] &, {ll, ur}];
crop = ImageCrop[pic, Transpose[{ ImageDimensions[pic]}],
AspectRatio -> boxrat];
Inset[crop, Min /@ Transpose[{ll, ur}], {Left, Bottom},
Abs[ur - ll]]]


Combined with kguler's answer you get something like

Graphics[{EdgeForm[{Thickness[0.005], Black}],
FaceForm[White], Rectangle[{0, 0}, {160, 90}],
FaceForm[Darker[Gray]], Rectangle[{0, 0}, {80, 63}],

(* code for picture *)
{rec[{80, 0}, {160, 63}, pic],
FaceForm[Opacity[0]],
Rectangle[{80, 0}, {160, 63}]},

(* code for text *)
Inset[Pane[
Style[txt1, 12, TextAlignment -> Left], {Scaled[1],
Scaled[0.75]}, Alignment -> Center,
ImageSizeAction -> "Scrollable"], {0, 8}, {Left, Bottom}, {78,
67}],

Flatten[
Transpose[{Flatten[(Table[
RandomChoice[{GrayLevel[0.15], c0[[#1]]}], {3}] &) /@
Range[2, 4, 1]],
Function[{Xs, Ys},
Rectangle[{Xs, Ys}, {Xs + 16, Ys + 9}]], {Flatten[
Table[Range[0, 32, 16], {3}]],
Flatten[(Table[#1, {3}] &) /@ Range[63, 81, 9]]}]}]],
{Black, Thickness[0.005], Line[{{0, 63}, {159, 63}}]}},
PlotRange -> {{0, 160}, {0, 90}}, Method -> {"ShrinkWrap" -> True},
ImagePadding -> 2, ImageMargins -> 0, ImageSize -> 500]


which produces something like

thank You very much, is this solution compatible with the one of kguler in http://mathematica.stackexchange.com/questions/1229/generate-random-text-within-a-rectangle I cannot assemble your 2 solutions to have both in one Graphics []

– 500 – 2012-02-03T14:59:14.990

@500 see updated answer – Heike – 2012-02-03T15:46:47.310

thank You very much for your attention. When i try to export it, I get only one line of the text. And on the output within the .nb, I need to click to see the text appear. Any idea how to fix this ? – 500 – 2012-02-03T15:51:53.393

@500 Are you using the updated version of rec? I got the behaviour you described with the previous one using Texture but not with the newest one using Inset. Maybe you need to run Clear[rec] first to clear the old definition. As for exporting, to what format are you exporting? – Heike – 2012-02-03T16:03:56.597

Now I do, thank You so much ! – 500 – 2012-02-03T16:07:35.123

1

I would use something along these lines, (borrowing from an earlier answer).

The test image, House2, is clipped, then set into the main graphic.

block1 = Graphics[{Red, Rectangle[{0, 0}, {150, 210}]},
PlotRange -> {{0, 150}, {0, 210}}];

block2 = Graphics[{Blue, Rectangle[{0, 0}, {150, 210}]},
PlotRange -> {{0, 150}, {0, 210}}];

image = ExampleData[{"TestImage", "House2"}];

clippedimage =
Graphics[{Green, Rectangle[{0, 0}, {500, 270}],
Inset[image, {250, 170}, {Center, Center}, {512, 512}]},
PlotRange -> {{0, 500}, {0, 270}}, ImageSize -> 500];

Graphics[{Yellow, Rectangle[{0, 0}, {330, 400}],
Inset[block1, {75, 295}, {Center, Center}, {150, 210}],
Inset[block2, {255, 295}, {Center, Center}, {150, 210}],
Inset[clippedimage, {165, 90}, {Center, Center}, {330, 179}]},
PlotRange -> {{0, 330}, {0, 400}}, ImageSize -> 330]