ImageMagick:使用多次转换的结果进行撰写(ImageMagick : Compose with results of multiple convert)
我想从其他人创建一个图像,这是他们自己的
convert
操作的结果,而不将中间结果保存到文件系统。很长的解释:
我有两个图像,两个需要特定的转换:
- avatar.jpg需要转换为圆形图像 - > rounded-avatar.jpg
- background.jpg需要应用颜色层 - > colored-background.jpg
然后我想在colored-background.jpg中
dissolve
rounded-avatar.png ,这样我得到的结果如下:+-----------+ | O | +-----------+到目前为止我所拥有的:
我知道如何按顺序进行这些操作(可能不是最好的方法,但这不是这个问题的主题),我甚至做了一个工作的bash脚本:
#!/bin/bash convert $1 -alpha set -background none -vignette 0x0 rounded-avatar.png convert $2 -auto-orient -thumbnail 600x313^ -gravity center -extent 600x313 -region 100%x100% -fill "#256997" -colorize 72% colored-background.jpg composite -dissolve 100 -gravity Center rounded-avatar.png colored-background.jpg -alpha Set $3
我可以称之为
$ ./myScript.sh avatar.jpg background.jpg output.jpg
我想要的是:
我想避免在文件系统上保存两个临时图像( rounded-avatar.jpg和colored-background.jpg )。
为什么?
- 此过程必须在Web平台上自动运行,我不希望必须使用命名技巧处理这些临时文件的并发性。
- 当前脚本使IM在内存中加载图像两次,重用计算的图像而不是将它们写入磁盘然后在新进程中加载它们可能更有效。
- 磁盘I / O现在很稀缺,让我们节省一些。
我希望我错过了正确的关键字,以便在文档中找到答案。
我知道这可能看起来过于优化而且我并没有在这里遇到C10k问题,但我只是想这样做(并理解IM语法)。
I want to create an image from to others, which are results of
convert
operations their self, without saving intermediate results to file system.Long explanation:
I have two images, the two needs specific transformations :
- avatar.jpg needs to be transformed to a rounded image -> rounded-avatar.jpg
- background.jpg needs to have a color layer applied -> colored-background.jpg
Then I want to
dissolve
rounded-avatar.png in colored-background.jpg, so that I get something looking like this:+-----------+ | O | +-----------+What I have so far:
I know how to make those operations sequentially (maybe not the best way but that is not the subject of this question), I even made a working bash script :
#!/bin/bash convert $1 -alpha set -background none -vignette 0x0 rounded-avatar.png convert $2 -auto-orient -thumbnail 600x313^ -gravity center -extent 600x313 -region 100%x100% -fill "#256997" -colorize 72% colored-background.jpg composite -dissolve 100 -gravity Center rounded-avatar.png colored-background.jpg -alpha Set $3
That I can call it with
$ ./myScript.sh avatar.jpg background.jpg output.jpg
What I want:
I want to avoid the saving of the two temporary images (rounded-avatar.jpg and colored-background.jpg) on the file system.
Why ?
- This procedure has to be ran automatically on a web platform, I don't want to have to handle concurrency on those temp files with naming tricks.
- The current script makes IM load the images two times in memory, it would probably be more efficient to reuse the computed images instead of writing them to disk and then load them in a new process.
- Disk I/O are scarcity these days, let's save some.
I hope I am just missing the right keywords to find the answer in the documentation.
I am aware that this might seems over optimisation and I am not struggling with C10k issues here, but I just want to do this right (and understand IM syntax).
原文:https://stackoverflow.com/questions/30673040
最满意答案
cols = ['sm','sb','mt','dv'] df[cols] = pd.DataFrame(df.apply(lambda x: foo(x[0], x[1]), 1).values.tolist(),columns= cols) print (df) 0 1 sm sb mt dv 0 1 2 3 -1 2 0.500000 1 3 4 7 -1 12 0.750000 2 5 6 11 -1 30 0.833333 3 7 8 15 -1 56 0.875000
解决方案与
concat
cols = ['sm','sb','mt','dv'] df[cols] = pd.concat(foo(df[0], df[1]), axis=1, keys=cols) print (df) 0 1 sm sb mt dv 0 1 2 3 -1 2 0.500000 1 3 4 7 -1 12 0.750000 2 5 6 11 -1 30 0.833333 3 7 8 15 -1 56 0.875000
也可以创建新的
DataFrame
然后concat
原始:cols = ['sm','sb','mt','dv'] df1 = pd.concat(foo(df[0], df[1]), axis=1, keys=cols) print (df1) sm sb mt dv 0 3 -1 2 0.500000 1 7 -1 12 0.750000 2 11 -1 30 0.833333 3 15 -1 56 0.875000 df = pd.concat([df, df1], axis=1) print (df) 0 1 sm sb mt dv 0 1 2 3 -1 2 0.500000 1 3 4 7 -1 12 0.750000 2 5 6 11 -1 30 0.833333 3 7 8 15 -1 56 0.875000
You can use
apply
+DataFrame
constructor:cols = ['sm','sb','mt','dv'] df[cols] = pd.DataFrame(df.apply(lambda x: foo(x[0], x[1]), 1).values.tolist(),columns= cols) print (df) 0 1 sm sb mt dv 0 1 2 3 -1 2 0.500000 1 3 4 7 -1 12 0.750000 2 5 6 11 -1 30 0.833333 3 7 8 15 -1 56 0.875000
Solution with
concat
cols = ['sm','sb','mt','dv'] df[cols] = pd.concat(foo(df[0], df[1]), axis=1, keys=cols) print (df) 0 1 sm sb mt dv 0 1 2 3 -1 2 0.500000 1 3 4 7 -1 12 0.750000 2 5 6 11 -1 30 0.833333 3 7 8 15 -1 56 0.875000
Also is possible create new
DataFrame
and thenconcat
original:cols = ['sm','sb','mt','dv'] df1 = pd.concat(foo(df[0], df[1]), axis=1, keys=cols) print (df1) sm sb mt dv 0 3 -1 2 0.500000 1 7 -1 12 0.750000 2 11 -1 30 0.833333 3 15 -1 56 0.875000 df = pd.concat([df, df1], axis=1) print (df) 0 1 sm sb mt dv 0 1 2 3 -1 2 0.500000 1 3 4 7 -1 12 0.750000 2 5 6 11 -1 30 0.833333 3 7 8 15 -1 56 0.875000
相关问答
更多-
什么是有条件地返回函数的最pythonic方法(What is the most pythonic way to conditionally return a function)[2023-12-04]
给调用func1的结果命名相对便宜,所以我会这样做,但是写下如下函数: def func2(n): ret = func1(n) return ret if ret is not None else something_else Giving a name to the result of calling func1 is relatively cheap, so I'd do that, but write the function like this: def func2(n): ... -
绝对(就你提供的例子)。 元组是Python中的一流公民 有一个内建的函数divmod()可以做到这一点。 q, r = divmod(x, y) # ((x - x%y)/y, x%y) Invariant: div*y + mod == x 还有其他的例子: zip , enumerate , dict.items 。 for i, e in enumerate([1, 3, 3]): print "index=%d, element=%s" % (i, e) # reverse keys ...
-
在这么短的情况下,我宁愿: def get_val(self): return x 它对于有经验的程序员来说是可读的(他们知道Python) 性能比下面的任何东西都要快,尽管差别很小 其次,在我看来仍然pythonic(通常在codewars.com看到): def get_val(self): return True if x else False 但我想,风格指南将推荐: def get_val(self): if x: return True els ...
-
如果这种情况经常发生,你可以分解丑陋: def filtered(f, x): if f: status, result = f(x) return result if status else x else: return x 用过像 returnlist.append(filtered(filterfunc, mystr[startpos:nextitem])) 因此,如果您有许多类似的可选过滤器,则代码仍然可读。 这是有效的,因为在Py ...
-
在这个函数中传递kwargs的最pythonic方法是什么?(What is the most pythonic way to pass kwargs in this function?)[2022-03-15]
def new_q(question_text = '', **kwargs): time = timezone.now() + timedelta(**kwargs) ... 这仍然非常简洁:它提到了两次kwargs ,但没有任何offset或其他任何额外的东西。 def new_q(question_text = '', **kwargs): time = timezone.now() + timedelta(**kwargs) ... This is still p ... -
我想你可以改变: return[trueWindSpeed, trueWindDirection] 至: return pd.Series([trueWindSpeed, trueWindDirection]) 接着: df_truewindtmp[['fld_trueWindSpeed','fld_trueWindDirection']] = df_truewindtmp.apply( lambda row: calcTrueWind(row['fld_courseOverGround'], ...
-
我不太了解行循环。 无论如何,为了保持数字的一致性,我把np.random.seed(1)放在顶部 总之,我认为你可以通过函数,groupby和调用.transform()实现你想要的。 def do_regression(y): X=np.array(range(len(y))).reshape(len(y),1) regr.fit(X,y) return regr.predict(X) df_regressed = df2.groupby(level=[0,1]).transf ...
-
一种有效的方法是使用pd.Series.map : df['num2'] += df['cls'].map({'a': 10, 'b': -10}) 这使用字典将cls值映射到10或-10。 还有许多其他方法(请参阅@ Guybrush的答案 ),但基于字典的方法对于较大的数据帧是可扩展且高效的。 在我看来,它也是可读的。 相关: 有效地通过字典替换大熊猫系列中的值 One efficient method is to use pd.Series.map: df['num2'] += df['cls']. ...
-
应用函数和返回多列的最pythonic方法是什么?(What is the most pythonic way to apply a function on and return multiple columns?)[2022-05-29]
您可以使用apply + DataFrame构造函数: cols = ['sm','sb','mt','dv'] df[cols] = pd.DataFrame(df.apply(lambda x: foo(x[0], x[1]), 1).values.tolist(),columns= cols) print (df) 0 1 sm sb mt dv 0 1 2 3 -1 2 0.500000 1 3 4 7 -1 12 0.750000 2 5 ... -
正如Gennady Kandaurov所指出的那样:你需要测试foo() '有效'返回值,它们不是'真实'(如0 , [] , () ,...): try: a = foo() if foo() is not None else b except AttributeError: a = b 根据foo的实现细节(无论是昂贵还是有副作用),您可能只想调用一次: try: f = foo() a = f if f is not None else b except Attrib ...