Photoshop plug-in: Access layer information in C++ - c++

I am currently writing a plug-in for Photoshop to save layer data into an .xml file, so far I've had no trouble (other than the bleak Adobe SDK) finding information such as layer names, the amount of layers, the document name, the dimensions of the document and more. However, I cannot find out how to access the dimensions and position of a layer, the SDK has been no help and I was wondering if someone had any experience on this?
For reference, here is the code to access the name of the layer:
OSErr PIGetLayerName(const int32 index, string & layerName)
{
Handle h = NULL;
OSErr error = sPSProperty->getPropertyProc(kPhotoshopSignature,
propLayerName,
index, NULL, &h);
if (!error && h != NULL)
{
error = HandleToString(h, layerName);
sPSHandle->Dispose(h);
}
return error;
}
"propLayerName" and "kPhotoshopSignature" are defined in "PIProperties.h" (included in the SDK)
similar definitions of "propTitle" (to get the document name) are also there.
However there are no such definitions for finding the dimensions, bounds, width and height - whatever it may be called - of the layer.
If anyone has any information I would be extremely grateful if you could post it.
Thanks in advance,
Harry

Related

Problem getting OpenCV multitracking to work

I'm in the early stages (VERY alpha) of writing the backend for an open source home video surveillance system. I'm building it on Gstreamer as a series of plugins. The idea is going to make each step of the process modular based on implementations, so that anyone can write a custom module and use that in the pipeline. For an example, take a look at "odo-lib-opencv-yolo" in the repo linked below. Using that as a template, anyone can write their own detection lib using any library or neural network model as use it within this pipeline. I also plan to expand that out to include a few "default" libraries that are optimized for different systems (Nvidia GPUs, Raspberry Pis, Coral TPUs, etc).
The issue I'm running into is the tracking portion. I wanted to start off with a simple and basic tracking system using the tracking API in OpenCV as a "filler" while I flesh out everything else. But it just doesn't seem to work right.
Here's the link to the repo: https://github.com/CeeBeeEh/Odo-Project
Of most importance is this code block in gst/gstodotrack.cpp at line 270:
if (meta->isInferenceFrame) {
LAST_COUNT = meta->detectionCount;
TRACKER->clear();
TRACKER = cv::legacy::MultiTracker::create();
for (int i=0; i<LAST_COUNT; i++) {
LAST_DETECTION[i].class_id = meta->detections[i].class_id;
LAST_DETECTION[i].confidence = meta->detections[i].confidence;
strcpy(LAST_DETECTION[i].label, meta->detections[i].label);
cv::Rect2i rect = cv::Rect2i(meta->detections[i].box.x, meta->detections[i].box.y,
meta->detections[i].box.width, meta->detections[i].box.height);
TRACKER->add(create_cvtracker(odo), img, rect);
}
GST_DEBUG("Added %zu objects to tracker", LAST_COUNT);
}
else {
meta->detectionCount = LAST_COUNT;
std::vector<cv::Rect2d> tracked;
if (!TRACKER->update(img, tracked)) GST_ERROR("Error tracking objects");
GST_DEBUG("Infer count=%lu, tracked count=%zu", LAST_COUNT, tracked.size());
for (int i=0; i<tracked.size(); i++) {
meta->detections[i].box.x = tracked[i].x;
meta->detections[i].box.y = tracked[i].y;
meta->detections[i].box.width = tracked[i].width;
meta->detections[i].box.height = tracked[i].height;
meta->detections[i].class_id = LAST_DETECTION[i].class_id;
meta->detections[i].confidence = LAST_DETECTION[i].confidence;
strcpy(meta->detections[i].label, LAST_DETECTION[i].label);
}
}
Variables at top of file:
cv::Ptr<cv::legacy::MultiTracker> TRACKER;
ulong LAST_COUNT = 0;
DetectionData LAST_DETECTION[DETECTION_MAX] = {};
I originally had
TRACKER = cv::legacy::MultiTracker::create();
in the start method to create it when the plugin is loaded, but that caused a segfault.
I've also tried creating a fixed size array of cv::Ptr<cv::Tracker> and just use each one for a single object with the same id within each frame, and then recycle each one for each inference frame. But that cause odd behaviour with each object was tracking to the same size and position within the frame.
Right now, in the current configuration, the tracking is dog-slow. It's actually faster to just inference each frame on GPU than inference a single frame and track for x additional frames. It should be the opposite.
It seems as though OpenCV's tracking API has changed as of 4.5.1, but I'm not sure if that's the cause of the issue.
I'm looking for help in sorting out the OpenCV tracking issue. I find all the docs very lacking in explaining the what and why of the multi-tracking API. So those are not of much help.

Landscape Creation C++ UE4.27

I would like to create a landscape from scratch in unreal engine 4.27 using C++ only. I have only a simple notion of the process, which revolves around GetWorld()->SpawnActor<ALandscape>, ALandscapeProxy::Import(...) and importing a height/weight map.
I used the LandscapeEditorDetailCustomization_NewLandscape::OnCreateButtonClicked() method as a learning ground, but unfortunately I am at an impasse.
From what I have gathered from my searches there not a lot of examples on the matter. Does anyone have a suggestion or an example?
This is the solution I came up with, with many thanks to ChenHP (or chpsemail) who gave me a solution to this. Firstly, declare the following variables. A better understanding can be found here.
FQuat InRotation
FVector InTranslation
FVector InScale
FTransform LandscapeTransform{InRotation, InTranslation, InScale}
int32 QuadsPerSection
int32 SectionsPerComponent
int32 ComponentCountX
int32 ComponentCountY
int32 QuadsPerComponent
int32 SizeX
int32 SizeY
Create containers for the heights and materials of the landscape:
TArray<FLandscapeImportLayerInfo> MaterialImportLayers
TMap<FGuid, TArray<uint16>> HeightDataPerLayers
TMap<FGuid, TArray<FLandscapeImportLayerInfo>> MaterialLayerDataPerLayers
It is important to note that heights in UE4 are of uint16 type, with 0 the deepest and 65'534 the highest. So for a flat map all height entries should be 32768.
The number of heights is the resolution of the map which is dependent on SizeX and SizeY.
TArray<uint16> HeightData;
HeightData.SetNum(SizeX * SizeY);
for (int32 i = 0; i < HeightData.Num(); i++)
{
HeightData[i] = 32768;
}
Height and material information should then be placed in the corresponding containers and be given a valid FGuid.
HeightDataPerLayers.Add(FGuid(), MoveTemp(HeightData))
MaterialLayerDataPerLayers.Add(FGuid(), MoveTemp(MaterialImportLayers))
At this point the base parameters for the landscape have been set. The ALandscape* Landscape = SpawnActor<ALandscape>() could be called at either point since it just spawns an object that doesn't actually have any information about it. This also applies for setting landscape's fields. Fields that need to be set are presented bellow:
Landscape->bCanHaveLayersContent
Landscape->LandscapeMaterial
Landscape->SetActorTransform
Landscape->StaticLightingLOD
ULandscapeInfo* LandscapeInfo = Landscape->GetLandscapeInfo()
LandscapeInfo->UpdateLayerInfoMap(Landscape)
Landscape->RegisterAllComponents()
Landscape->GetClass()
Landscape->PostEditChangeProperty(MaterialPropertyChangedEvent)
Landscape->PostEditChange()
The actual part where landscape is given form, happens with the invocation of Landscape->Import(...).
A detailed explanation about what the script could look like can be found here with more information on landscape (check the answer for the cpp code).

VSIX how to get current snapshot document name?

I have been trying to to create an extension that highlights specific line numbers for me in Visual Studio in the margins.
I manged to get my marking in the margins using predefined line number but for it to work properly I need to know what the current document FullName is (Path and filename)
After much googling I figured out how to do it with the sample code (which is not ideal)
DTE2 dte = (DTE2)System.Runtime.InteropServices.Marshal.GetActiveObject("VisualStudio.DTE.15.0");
var activeDocument = dte.ActiveDocument;
var docName = activeDocument.Name;
var docFullName = activeDocument.FullName;
Now I know the problems here
is that is for specific version bases on the text
there is no way to select which instance (when running more than one VS)
It seems to be very slow
I have a feeling I should be doing this with MEF Attributes but the MS docs examples are so simple that they do not work for me. I scanned a few SO questions too and I just cannot get them to work. They mostly talk about Services.. which I do not have and have no idea how to get.
The rest of my code uses SnapshotSpans as in the example Extension of Todo_Classification examples which is great if you do NOT need to know the file name.
I have never done any extensions development. Please can somebody help me do this correctly.
You can use following code to get a file from a snapshot without any dependencies.
public string GetDocumentPath(Microsoft.VisualStudio.Text.ITextSnapshot ts)
{
Microsoft.VisualStudio.Text.ITextDocument textDoc;
bool rc = ts.TextBuffer.Properties.TryGetProperty(
typeof(Microsoft.VisualStudio.Text.ITextDocument), out textDoc);
if (rc && textDoc != null)
return textDoc.FilePath;
return null;
}
If you don't mind adding Microsoft.CodeAnalysis.EditorFeatures.Text to your project it will provide you with an extension method Document GetOpenDocumentInCurrentContextWithChanges() on the Microsoft.VisualStudio.Text.Snapshot class. (Plus many other Rosyln based helpers)
using Microsoft.CodeAnalysis.Text;
Document doc = span.Snapshot.GetOpenDocumentInCurrentContextWithChanges();

nodejs native c++ npm module memory error, cairo image processing

I've been bugging TJ on node-canvas about a code speed up I'm working on in a fork of a node module he authored and maintains.
I found Canvas.toBuffer() to be killing our pipeline resources and created an alternative that would simply convert from Canvas into an Image without going through a png buffer/media url. The problem is that cairo is a mysterious beast, and there's an additional level of concern about memory allocated within node modules as not to get GC'd by mother v8. I've added the proper HandleScopes to all required functions which access V8 data.
I was able to test the Canvas.loadImage(image) method thousands of times on my mac setup (6.18), as well as stand alone tests on our ubuntu/production servers running the same version of node. But when the code is run as a background process/server and coordinated by Gearman I'm getting some "interesting" memory/segfaults.
In addition I'm having trouble calling any of the methods of classes defined in node-canvas that aren't inline within header files. As a side question What's the best way to create common native source code packages that other node modules can rely on?
I've tried recreating the problem and running it with gdb, node_g, and all the node modules built with symbols and debug flags. But the error crops up in a lib outside of the source I can get a stack trace for.
for reference here's where I call loadImageData and while it runs locally under a variety of conditions, in our production environment when carefully tucked away within a frame server it appears to be causing segfaults (spent the day yesterday trying to gdb node_g our server code but the frame servers are kicked off by gearman... TL;DR didn't get a root cause stack trace)
https://github.com/victusfate/node-canvas/blob/master/src/Canvas.cc#L497
Handle<Value>
Canvas::LoadImage(const Arguments &args) {
HandleScope scope;
LogStream mout(LOG_DEBUG,"node-canvas.paint.ccode.Canvas.LoadImage");
mout << "Canvas::LoadImage top " << LogStream::endl;
Canvas *canvas = ObjectWrap::Unwrap<Canvas>(args.This());
if (args.Length() < 1) {
mout << "Canvas::LoadImage Error requires one argument of Image type " << LogStream::endl;
return ThrowException(Exception::TypeError(String::New("Canvas::LoadImage requires one argument of Image type")));
}
Local<Object> obj = args[0]->ToObject();
Image *img = ObjectWrap::Unwrap<Image>(obj);
canvas->loadImageData(img);
return Undefined();
}
void Canvas::loadImageData(Image *img) {
LogStream mout(LOG_DEBUG,"node-canvas.paint.ccode.Canvas.loadImageData");
if (this->isPDF()) {
mout << "Canvas::loadImageData pdf canvas type " << LogStream::endl;
cairo_surface_finish(this->surface());
closure_t *closure = (closure_t *) this->closure();
int w = cairo_image_surface_get_width(this->surface());
int h = cairo_image_surface_get_height(this->surface());
img->loadFromDataBuffer(closure->data,w,h);
mout << "Canvas::loadImageData pdf type, finished loading image" << LogStream::endl;
}
else {
mout << "Canvas::loadImageData data canvas type " << LogStream::endl;
cairo_surface_flush(this->surface());
int w = cairo_image_surface_get_width(this->surface());
int h = cairo_image_surface_get_height(this->surface());
img->loadFromDataBuffer(cairo_image_surface_get_data(this->surface()),w,h);
mout << "Canvas::loadImageData image type, finished loading image" << LogStream::endl;
}
}
and here's what the current method in Image looks like (I removed some commented out logging info)
https://github.com/victusfate/node-canvas/blob/master/src/Image.cc#L240
/*
* load from data buffer width*height*4 bytes
*/
cairo_status_t
Image::loadFromDataBuffer(uint8_t *buf, int width, int height) {
this->clearData();
int stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width); // 4*width + ?
this->_surface = cairo_image_surface_create_for_data(buf,CAIRO_FORMAT_ARGB32,width,height,stride);
this->data_mode = DATA_IMAGE;
this->loaded();
cairo_status_t status = cairo_surface_status(_surface);
if (status) return status;
return CAIRO_STATUS_SUCCESS;
}
Any help, pro tips, assistance, or words of encouragement would be appreciated.
Originally from google groups
Got it!
I was working on another library today that uses cairomm and discovered surfaces created from data buffers require those buffers to live on as long as the surface does.
http://www.cairographics.org/manual/cairo-Image-Surfaces.html#cairo-image-surface-create-for-data
"Creates an image surface for the provided pixel data. The output buffer must be kept around until the cairo_surface_t is destroyed or cairo_surface_finish() is called on the surface. The initial contents of data will be used as the initial image contents; you must explicitly clear the buffer, using, for example, cairo_rectangle() and cairo_fill() if you want it cleared."
I introduced a surface that was created from a temporary buffer.
Easy solution in node-canvas fork:
There's a member variable called _data which I can assign a locally malloced data buffer to, which will live on as long as the cairo surface does.
Solution:
A general way to copy a buffer into a surface is to create a temporary surface from the buffer, then draw from the temporary surface onto an allocated surface and let cairo manage it's own memory.
It would look something like this with the c api to cairo to implement.
cairo_surface_t *pTmp = cairo_image_surface_create_for_data (
data
, CAIRO_FORMAT_ARGB32
, width
, height
, cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width));
_surface = cairo_image_surface_create ( CAIRO_FORMAT_ARGB32
, width
, height);
cairo_t *cr = cairo_create (_surface);
cairo_set_source_surface (cr, pTmp, x, y);
cairo_paint (cr);
In addition I'm having trouble calling any of the methods of classes
defined in node-canvas that aren't inline within header files. As a
side question What's the best way to create common native source code
packages that other node modules can rely on?
While I don't have an answer for the memory issue/seg fault I was running into in our staging environment. I do have an answer for constructing reusable libraries with native node modules.
I'm using git submodules for all the independent native node modules, and added a conditional preprocessor definition for each of their wscript or binding.gyp files to specify whether or not to generate a shared object .node module.
update Alternatively unique init function names or namespaces can surround the module initialization call (moved to this setup).
In addition I'll be using this new package to aid in debugging or rewriting code sections (I can't spend too much time debugging utilization of several remote libraries).
in wscript or binding.gyp
flags = ['-D_NAME_NODE_MODULE', '-O3', '-Wall', '-D_FILE_OFFSET_BITS=64', '-D_LARGEFILE_SOURCE', '-msse2']
then in an initialization file
#ifdef _NAME_NODE_MODULE
extern "C" {
static void init(Handle<Object> target) {
HandleScope scope;
NODE_SET_METHOD(target, "someFunction", someFunction);
}
NODE_MODULE(moduleName, init);
}
#endif
This way a node native module is only added to when the flag is set. Otherwise it can be linked to normally (like in another node module).

Use c++ to access internet explorer

Well as the topic says, I want to know if there is a tool or a tutorial that can help me access IE, get in a certain URL, do some action on that website. So I would have a program to do that for me instead of doing it myself every time.
Here is a project on Internet Explorer automation with C++
you should really rephrase your question.. you said what you want to do is login to hotmail programatically, check the pidgin code, they do it.
Documentation found here , here and you can I think navigate through the code and tutorials at will until you have your understanding of how the pidgin contributors did it.
You can find the main page for pidgin here
Code sample to get you started:
00362 static void
00363 msn_show_hotmail_inbox(PurplePluginAction *action)
00364 {
00365 PurpleConnection *gc;
00366 MsnSession *session;
00367
00368 gc = (PurpleConnection *) action->context;
00369 session = gc->proto_data;
00370
00371 if (session->passport_info.file == NULL)
00372 {
00373 purple_notify_error(gc, NULL,
00374 _("This Hotmail account may not be active."), NULL);
00375 return;
00376 }
00377
00378 purple_notify_uri(gc, session->passport_info.file);
00379 }
00652 void *
00653 purple_notify_uri(void *handle, const char *uri)
00654 {
00655 PurpleNotifyUiOps *ops;
00656
00657 g_return_val_if_fail(uri != NULL, NULL);
00658
00659 ops = purple_notify_get_ui_ops();
00660
00661 if (ops != NULL && ops->notify_uri != NULL) {
00662
00663 void *ui_handle = ops->notify_uri(uri);
00664
00665 if (ui_handle != NULL) {
00666
00667 PurpleNotifyInfo *info = g_new0(PurpleNotifyInfo, 1);
00668 info->type = PURPLE_NOTIFY_URI;
00669 info->handle = handle;
00670 info->ui_handle = ui_handle;
00671
00672 handles = g_list_append(handles, info);
00673
00674 return info->ui_handle;
00675 }
00676 }
00677
00678 return NULL;
00679 }
Rather than using IE for such things, look into appropriate screen scraping libraries for your language of choice. You can google and search Stack Overflow to find many such libraries. From here, you'll use your language's web APIs to send data to the server.
Don't know of any tool.
I use an embedded browser for such things. It is possible to connect to a running instance of IE. See
Connect to Running Instance of IE
Once you get an instance of IWebBrowser2, the coding is the same.
1. Get the Document Interface
pWebBrowser->Document->QueryInterface(
IID_IHTMLDocument2,(LPVOID*)&Doc);
2. Get all the elements on the Document
Doc->get_all(&Elements);
3. enum the Elements
Elements->get_length(&ulLen);
for_each
Elements->item(item, index, &ppvElement);
4. Detemine what element is desired.
* by classname
* by ID etc.. here I used the classname
ppvElement->get_className (&bstrElement);
5. Insert Text for user / password
ppvElement->put_innerText(wsUreser_or_Psswd)
6. Find the Sign in button and click it.
ppvElement->Click();
Your results may vary.
--
Michael
Why don't you make a feed in dapper in two minutes? Apparently some people have already done it as well.