PHP - 多个用户同时编辑同一张图像

发布于 2024-08-12 23:46:49 字数 168 浏览 2 评论 0原文

我希望让多个用户使用 gd 库的 imagecopymerge 功能编辑同一图像。

我担心两个用户可能会选择同时编辑图像。然后,应用程序分别合并两个用户图像并最终保存它们,但其中一个会覆盖另一个,因此其中一个用户图像丢失。

我不确定如何测试上述内容...是否有可能,如果有的话我该如何应对?

I am looking to have multiple users edit the same image using the gd library's imagecopymerge function.

I am worried that two users might select to edit the image at the same time. The application then merge's the two users images seperately and finally saves them but one overwrites the other and thus one of the users images is missing.

I am not sure of how to test the above... is it a possibility and if so how can I combat it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

以可爱出名 2024-08-19 23:46:49

当用户开始编辑图像时存储最后修改的时间戳。当他们提交更改时,再次检查上次修改的时间戳。如果不同,请通知用户其他用户已经修改了该图像。

您可能想让用户在选择覆盖之前看到图像的新版本。另外,您可能希望提供一个版本控制系统(维基百科)来让人们回滚更改。

编辑(回应下面的评论)

  1. 与存储最后修改的时间戳相反(或者可能除此之外),存储原始图像的哈希值。并在覆盖之前立即比较它们。否则与上面相同。

  2. 正如您所建议的,另一种选择也可以很好地发挥作用。在工作流程的第 3 步,在流程开始时创建一个 [imagefilename].lock 文件(或者修改数据库中的字段,如果它们存储在那里),如果该文件尚不存在,当然如果确实存在,那么与上面相同。

  3. 要扩展上面第 2 点中的 DB 选项,拥有一个如下表会简单得多:
    图像ID |图像数据

    开始时包含 md5 的查询(可以选择在 php 中计算 md5,以减少数据库的负载)

    从 image_table 中选择 image_data, md5(image_data),其中 image_id=1
    

    然后当你想回信时,就这样做

    更新 image_table 设置 image_data=?其中 image_id=?和 md5(image_data)=?
    

    这使得更新的条件是 md5 在被覆盖之前相同,并且它保留在单个简单的查询中。

    然后检查受影响的行。如果没有行受到影响,则检查哈希值。如果哈希值不同,则可能是由于 md5 检查导致查询更新失败。 (注意:您可能还想检查是否有任何 mysql 错误)

Store the last-modified timestamp when the user begins editing an image. when they submit their changes, check against the last-modified timestamp again. If it's different, inform the user than another user has already modified the image.

You might want to let the user see the new version of the image before choosing to overwrite. Also, you may want to provide a version control system (a la wikipedia) to let people roll back changes.

EDIT (In response to comments below)

  1. As opposed to storing the last modified time stamp (or perhaps in addition to), store a hash of the original image. and compare those immediately before overwriting. Otherwise same as above.

  2. The other option, as you suggested would also work well. at step 3 in your workflow create an [imagefilename].lock file (or modify a field in the DB if they are stored there) at the beginning of the process if one doesn't already exist, of course if one does exist, then same as above.

  3. To expand on the DB option in point 2 above, it would be much simpler to have a table like:
    image_id | image_data

    query including the md5 when you begin (optionally compute the md5 in php instead to reduce load on your db)

    select image_data, md5(image_data) from image_table where image_id=1
    

    Then when you want to write back, do

    update image_table set image_data=? where image_id=? and md5(image_data)=?
    

    This makes the update conditional on the md5 being identical before being overwritten, and it remains in a single, simple query.

    Then check the affected_rows. If no rows were affected, then check the hash. If the hash is different then presumably the query failed to update due to the md5 check. (Note: you will probably also want to check for any mysql errors)

忱杏 2024-08-19 23:46:49

啊,你基本上想要的是保存相对于原始图像的增量

一种方法:

  1. 用户 Fred 获取原始源图像 I1 并对其进行编辑。 Fred 发回整个新图像 N1
  2. 您计算图像 D1 的增量,即 {N1 - O}。您不是仅保存覆盖 N1,而是从磁盘检索当前图像 I2,该图像同时可能已更改(I1 不需要等于 I2)。您将 D1 应用于 I1 并用生成的图像覆盖图像,我们将其称为 I3。
    请注意,您需要记住 I1 才能在 $_SESSION 中工作。
  3. 现在,另一个 Ria 可以在前面的步骤中编辑相同的图像。例如,在 Fred 获得 I1 后不久,Ria 也获得了 I1。就在 Ria 完成工作之前,Fred 将他的增量保存在磁盘上,结果是 I3,就像我们看到的那样。那么现在怎么办?
    你盲目地应用步骤 2。我将展示会发生什么:User2 提交他的工作 N2,增量 D2 是通过比较 I1 与 N2 计算的(Ria 的会话包含 I1)。当前图像是从磁盘检索的,您可能记得正确的是 I3。该增量 D2 应用于 I3,生成 I4,并将其保存到磁盘。结果是 Ria 覆盖了 I3,但只覆盖了她实际编辑过的部分。

这个方法会起作用,因为文件保存是 php 中的原子操作。

要实现此操作

  1. 您需要确保当用户 A 检索要编辑的图像时,我需要存储在A的session中。简单的。
  2. 您需要能够计算图像的差异,并将此差异应用于图像。例如,这应该可以通过 imagemagick 的比较函数实现。查看该网址的示例,您会发现差异中的白色像素是未触及的像素。

Ah, what you basically want is saving the delta with respect to the original images.

One way:

  1. A user Fred fetches the original source image I1 and edits it. Fred posts back the whole new image N1
  2. You compute the delta of the image D1, that is {N1 - O}. Instead of saving just overwriting N1, you retrieve the current image I2 from disk which might have been changed in the meantime (I1 doesn't need to equal I2) . You apply D1 to I1 and overwrite the image with the resulting image, which we call I3.
    Beware, you need to remember I1 for this to work in $_SESSION for example.
  3. Now an other Ria could edit the same image during the previous steps. For instance, shortly after Fred got I1, Ria got it too. Just before Ria has finished her work, Fred has had his delta saved on disk resulting in I3, like we saw. So what now?
    You blindly apply step 2. I will show what happens: User2 submits his work N2, the delta D2 is computed by comparing I1 with N2 (The session for Ria contains I1). The current image is retrieved from disk, which is I3 as you might correctly remember. This delta D2 is applied to I3 resulting in I4, which is saved to disk. Result is that Ria has overwrited I3, but only those parts she has actually edited.

This recipe will work, because file saving is an atomic operation in php.

To get this working:

  1. you need to ensure when a user A retrieves an image I to edit, I needs to be stored in A's session. Easy.
  2. You need to be able to compute a diff of the image, and apply this diff to an image. This should be possible with imagemagick's compare function for instance. Looking at the example of that url you'll see that in the diff white pixels are those that untouched.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文