Using PyMuPDF "draw_rect" function is working inconsistent - python

I'm blacking out some information from several PDF's but there are some of these that the rectangles made by "draw_rect" functions are't being drawn correctly. I have checked the rectangles and they look right, that and I'm also usind the "add_redact_annot" with the exact same rectangle and works good.
def hide_text_rects(page, rects):
for rect in rects:
page.add_redact_annot(rect)
page.draw_rect(rect, color=(0,0,0), fill=(0,0,0))
The rectangles seem to be mirrored and zoomed (scaled). I really don't know what to do because I don't find any info related in the docs.
Edit: I found that the PDF's with version 1.7 are the ones working correctly. And the other ones are version 1.5.

The probable reason for this behaviour is a sloppy specification of the page's coordinate system.
For example the standard point (0,0) = bottom-left in PDF may have been redefined to be top-left.
If this type of coordinate change is not wrapped within PDF stacking operators q / Q (as it should), then any insertions (of text, drawing etc.) appended to the page /Contents act under wrong assumptions, and appear dislocated.
Heal this by executing page.clean_contents() before do any insertion.
You can also check if this is required at all by page.is_wrapped. Please also consult the documentation - there is an own section dealing with this.

Related

How to get the largest possible rectangle contained inside polygon

I am looking for a solution to get the largest possible rectangle inside a polygon.
currently I am using Arcpy for ArcGIS (python library), but there is no out of the box solution for getting it, instead there is a feature named Minimum Bounding Geometry (this returning the opposite result, a rectangle contains the polygon):
https://pro.arcgis.com/en/pro-app/latest/tool-reference/data-management/minimum-bounding-geometry.htm
Example of the required result:
The best I've found is described in an academic paper titled "Finding the largest area rectangle of arbitrary orientation in a closed contour". Available in PDF, but copyright precludes me from linking the doc, which you can get to via the publisher https://www.sciencedirect.com/science/article/abs/pii/S0096300312003207.
The algorithm is O(N^3) and the authors claim there is no other with lower time complexity (which does NOT imply that it is most efficient for all use cases).
(My implementation (C#) was for a client who owns the code, so you will have to roll your own version unless it's been open sourced in the meantime.)

Absolute positions in mpld3 graphs

I'm trying to define a custom plugin for mpld3, and I'm struggling with positions. More particularly, by default, SVG generated by mpld3 come with Move and Zoom buttons, which change the view of the graph. When I was trying to display things (like text), I stumbled upon a strange behavior where positions are set relatively to the current view. It means that if I display a text next to a point A(10,10) and then move the view, the point will still be at (10,10) but the text will move because its position is relative to the current view.
So I wanted to think again and start with a minimal example which should work : this example from the mpld3 documentation. In the demo, you can see the behavior I want : positions are absolute (when you move the view, cursor position is set according to the grid)..
But if I copy-paste the exact same code in Pycharm and execute it, positions are relative to the view which is even more strange :
My guess is it's a version problem. I don't know which versions are used in the hosted demo example. I use mpld3==0.5.1, matplotlib==3.2.1 and numpy==1.19.2.
Do you have an idea so I can manage to deal with absolute positions like in the example ?
I've managed to make it work. It turns out that downgrading mpld3 to version 0.3 does what I want. I'm sure there is a better solution (because I can't take advantage of the latest version) but it gets the job done.

Use python to identify elements at screen

I want to start a python project thats identify some elements in screen, like a square's size or all elements in screen with a certain color, and i don't even know from where should i start.
For example, all the top points above certain value at the graph.
Anyone could please give me a north?
If you're looking to interact with elements inside a browser, look at Selenium. If you want to control the desktop itself, look into Sikuli.
In either case, you can use OpenCV to identify elements and do template matching.
Edit: more comments after more details from OP
If you're just looking to identify the peaks in the graph, you can take a screenshot of the display at regular intervals using Sikuli or PyScreenshot and then use template matching in OpenCV (either directly or using Sikuli) to get the coordinates of the peaks in the screenshot. The horizontal line across the graph might throw off some of the template matching, but you can play around with the various parameters to get the results you want.
Check out this tutorial for template matching.

Color area under graph in manim

I am following this tutorial for manim: https://talkingphysics.wordpress.com/2019/01/08/getting-started-animating-with-manim-and-python-3-7/. Under heading 7.0: Graphing functions, the example shows code for plotting sine and cosine functions.
I was wondering if I could also fill the area covered between, let's say, sine function and the x-axis from x_min to x_max. I realized that the used PlotFunctions class has following hierarchy: PlotFunctions -> GraphScene -> Scene -> Container -> object (where -> denotes child of). But in this entire chain of hierarchy, I do not see a config option such as fill_color that is present in VMobject.
I'm also not readily able to locate any code that helps in doing so, although I'm sure that some really easy 1 line code must exist since this is used in so many 3blue1brown videos. I would really appreciate some help with this!
You can check this github issue, it might be something your'e looking for.
It hasn't been merged onto the main branch so this could be a work-around for now.
After looking more into the code, I still don't see a 1-liner code per se but did find that to color the area under the graph, a set of riemann rectangles of very small width (~0.01) are used. This makes the graph look colored.
I used get_point_from_function() option to get the points and passed them to create a Polygon filled with colour.
you can check it here , look at def get_region()

Snap 3D cursor to an opaque part of plane (blender)

I have a question regarding python scripting in Blender, and I'd really appreciate it if someone could give me at least some conceptual guidelines to how I could do this:
Basically I have around 100 planes (simple primitive planes) and each of them has its own material and each material has it's own transparency map applied to it.
I need a way to snap each of those plane's respective pivots to their opaque parts. I.e. if there is a way to tell the following to blender through python language - "hey, go over every one of these planes, and do the following for each - snap a 3D cursor to an opaque part of the plane (it doesn't matter where exactly, as long as it's inside of an opaque part of the plane) and then snap plane's pivot point to the 3D cursor".
Of course I don't expect anyone to write me a full algorithm for this, I am just asking for a little help and a push in the right direction, as I do have experience with python, but not with blender :/
Any help would be appreciated.
You can find documentation on blender's python api here.
Within blender's image class you can access the pixel data at image.pixels as an array of floats, 4 floats per pixel (RGBA I think). image.size[0] is the width in pixels image.size[1] for height.
Given bpy.data.objects['Plane'].bound_box is an [8][3] array of points defining the outer extremes of the plane, you can locate a point on the plane for the pixel location to get the target point for the origin. You will also find bpy.data.objects['Plane'].matrix_world useful to translate the object coordinates to global.
bpy.context.scene.cursor_location = Vector((x,y,z)) will move the cursor to where you want.
bpy.ops.object.origin_set(type='ORIGIN_CURSOR') will set the active objects origin to the cursor. Note that this works on the active object, so you will need to alter your selection as you go.

Categories

Resources